Problem/Motivation
\Drupal\language\Plugin\LanguageNegotiation::getLanguageSwitchLinks()
and \LanguageNegotiationContentEntity::getLanguageSwitchLinks() do not set a language
key in the links.
This can lead to incorrect switch links in the following situation (among others):
1. Add a language, so that you have at least two, let's say language A (let's say that's the default one) and language B (let's say with language code bb
).
2. Change language negotiation to be session-based (and disable URL negotiation).
3. Enable the language switcher block.
4. Create an alias for a path in language A, say /pathA
.
5. Create an alias for the same path in language B, say /pathB
.
6. Visit /pathA
.
At this point the language switcher should link to /pathB?language=bb
, but it instead links to /pathA?language=bb
Proposed resolution
Add the language to the switch links.
Instead of copy-pasting even more code into the already ~80% copy-pasted methods this patch provides a trait for code re-use. As you can see from this and other previous bugs in this area it is very hard to get this stuff right, so this is not for some theoretical purpose but it is to prevent future bugs in core and contrib.
Remaining tasks
<!-- See https://drupal.org/core-mentoring/novice-tasks for tips on identifying novice tasks. Delete or add "Novice" from the Novice? column in the table below as appropriate. Uncomment tasks as the issue advances. Update the Complete? column to indicate when they are done, and maybe reference the comment number where they were done. -->
User interface changes
None.
API changes
Due to the minor refactoring to improve future maintenance and stability this breaks contrib and custom language negotiation plugins if they extend LanguageNegotiationContentEntity
, LanguageNegotiationSession
or LanguageNegotiationUrl
and one of the following is true:
1. They provide a private method called getLanguageManager()
or processLanguageSwitchLink()
2. They provide a public or protected method called getLanguageManager()
that does not return an object implementing \Drupal\Core\Language\LanguageManagerInterface
3. They provide a public or protected method called processLanguageSwitchLink()
that takes different arguments from the ones introduced here.
3. They use a trait that has a method called getLanguageSwitchLinks()
or processLanguageSwitchLink()
.
If this is considered a BC break, then this could be avoided as well, by simplifying the patch at the cost of future maintenance and stability. We could also considering doing the improved version for 8.1 and the extra-safe version for 8.0.
Data model changes
None.