MediaWiki master
SpecialMyLanguage.php
Go to the documentation of this file.
1<?php
26namespace MediaWiki\Specials;
27
32
43
44 private LanguageNameUtils $languageNameUtils;
45 private RedirectLookup $redirectLookup;
46
51 public function __construct(
52 LanguageNameUtils $languageNameUtils,
53 RedirectLookup $redirectLookup
54 ) {
55 parent::__construct( 'MyLanguage' );
56 $this->languageNameUtils = $languageNameUtils;
57 $this->redirectLookup = $redirectLookup;
58 }
59
67 public function getRedirect( $subpage ) {
68 $title = $this->findTitle( $subpage );
69 // Go to the main page if given invalid title.
70 if ( !$title ) {
71 $title = Title::newMainPage();
72 }
73 return $title;
74 }
75
91 public function findTitle( $subpage ) {
92 return $this->findTitleInternal( $subpage, false );
93 }
94
109 public function findTitleForTransclusion( $subpage ) {
110 return $this->findTitleInternal( $subpage, true );
111 }
112
121 private function findTitleInternal( $subpage, $forTransclusion ) {
122 // base = title without the language code suffix
123 // provided = the title as it was given
124 $base = $provided = null;
125 if ( $subpage !== null ) {
126 $provided = Title::newFromText( $subpage );
127 $base = $provided;
128
129 if ( $provided && str_contains( $subpage, '/' ) ) {
130 $pos = strrpos( $subpage, '/' );
131 $basepage = substr( $subpage, 0, $pos );
132 $code = substr( $subpage, $pos + 1 );
133 if ( strlen( $code ) && $this->languageNameUtils->isKnownLanguageTag( $code ) ) {
134 $base = Title::newFromText( $basepage );
135 }
136 }
137 }
138
139 if ( !$base || !$base->canExist() ) {
140 // No subpage provided or base page does not exist
141 return null;
142 }
143
144 $fragment = '';
145 if ( $base->isRedirect() ) {
146 $base = $this->redirectLookup->getRedirectTarget( $base );
147 // Preserve the fragment from the redirect target
148 $fragment = $base->getFragment();
149 }
150
151 $uiLang = $this->getLanguage();
152 $baseLang = $base->getPageLanguage();
153
154 // T309329: Always use subpages for transclusion
155 if ( !$forTransclusion && $baseLang->equals( $uiLang ) ) {
156 // Short circuit when the current UI language is the
157 // page's content language to avoid unnecessary page lookups.
158 return $base;
159 }
160
161 // Check for a subpage in the current UI language
162 $proposed = $base->getSubpage( $uiLang->getCode() );
163 if ( $proposed && $proposed->exists() ) {
164 if ( $fragment !== '' ) {
165 $proposed->setFragment( $fragment );
166 }
167 return $proposed;
168 }
169
170 // Explicit language code given and the page exists
171 if ( $provided !== $base && $provided->exists() ) {
172 // Not based on the redirect target, don't need the fragment
173 return $provided;
174 }
175
176 // Check for fallback languages specified by the UI language
177 $possibilities = $uiLang->getFallbackLanguages();
178 foreach ( $possibilities as $lang ) {
179 // $base already include fragments
180 // T309329: Always use subpages for transclusion
181 // T333187: Do not ignore base language page if matched
182 if ( !$forTransclusion && $lang === $baseLang->getCode() ) {
183 return $base;
184 }
185 // Look for subpages if is for transclusion or didn't match base page language
186 $proposed = $base->getSubpage( $lang );
187 if ( $proposed && $proposed->exists() ) {
188 if ( $fragment !== '' ) {
189 $proposed->setFragment( $fragment );
190 }
191 return $proposed;
192 }
193 }
194
195 // When all else has failed, return the base page
196 return $base;
197 }
198
207 return true;
208 }
209}
210
215class_alias( SpecialMyLanguage::class, 'SpecialMyLanguage' );
A service that provides utilities to do with language names and codes.
Superclass for any RedirectSpecialPage which redirects the user to a particular article (as opposed t...
getLanguage()
Shortcut to get user's language.
Unlisted special page which redirects the user to the appropriate translated version of a page if it ...
findTitleForTransclusion( $subpage)
Find a title for transclusion.
personallyIdentifiableTarget()
Target can identify a specific user's language preference.
__construct(LanguageNameUtils $languageNameUtils, RedirectLookup $redirectLookup)
getRedirect( $subpage)
If the special page is a redirect, then get the Title object it redirects to.
Represents a title within MediaWiki.
Definition Title.php:78
Service for resolving a wiki page redirect.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...