MediaWiki  master
SpecialMyLanguage.php
Go to the documentation of this file.
1 <?php
26 namespace 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 
89  public function findTitle( $subpage ) {
90  return $this->findTitleInternal( $subpage, false );
91  }
92 
107  public function findTitleForTransclusion( $subpage ) {
108  return $this->findTitleInternal( $subpage, true );
109  }
110 
119  private function findTitleInternal( $subpage, $forTransclusion ) {
120  // base = title without language code suffix
121  // provided = the title as it was given
122  $base = $provided = null;
123  if ( $subpage !== null ) {
124  $provided = Title::newFromText( $subpage );
125  $base = $provided;
126 
127  if ( $provided && str_contains( $subpage, '/' ) ) {
128  $pos = strrpos( $subpage, '/' );
129  $basepage = substr( $subpage, 0, $pos );
130  $code = substr( $subpage, $pos + 1 );
131  if ( strlen( $code ) && $this->languageNameUtils->isKnownLanguageTag( $code ) ) {
132  $base = Title::newFromText( $basepage );
133  }
134  }
135  }
136 
137  if ( !$base || !$base->canExist() ) {
138  // No subpage provided or base page does not exist
139  return null;
140  }
141 
142  $fragment = '';
143  if ( $base->isRedirect() ) {
144  $base = $this->redirectLookup->getRedirectTarget( $base );
145  // Preserve the fragment from the redirect target
146  $fragment = $base->getFragment();
147  }
148 
149  $uiLang = $this->getLanguage();
150  $baseLang = $base->getPageLanguage();
151 
152  // T309329: Always use subpages for transclusion
153  if ( !$forTransclusion && $baseLang->equals( $uiLang ) ) {
154  // Short circuit when the current UI language is the
155  // page's content language to avoid unnecessary page lookups.
156  return $base;
157  }
158 
159  // Check for a subpage in current UI language
160  $proposed = $base->getSubpage( $uiLang->getCode() );
161  if ( $proposed && $proposed->exists() ) {
162  if ( $fragment !== '' ) {
163  $proposed->setFragment( $fragment );
164  }
165  return $proposed;
166  }
167 
168  // Explicit language code given and the page exists
169  if ( $provided !== $base && $provided->exists() ) {
170  // Not based on the redirect target, don't need the fragment
171  return $provided;
172  }
173 
174  // Check for fallback languages specified by the UI language
175  $possibilities = $uiLang->getFallbackLanguages();
176  foreach ( $possibilities as $lang ) {
177  // $base already include fragments
178  // T309329: Always use subpages for transclusion
179  // T333187: Do not ignore base language page if matched
180  if ( !$forTransclusion && $lang === $baseLang->getCode() ) {
181  return $base;
182  }
183  // Look for subpages if is for transclusion or didn't match base page language
184  $proposed = $base->getSubpage( $lang );
185  if ( $proposed && $proposed->exists() ) {
186  if ( $fragment !== '' ) {
187  $proposed->setFragment( $fragment );
188  }
189  return $proposed;
190  }
191  }
192 
193  // When all else has failed, return the base page
194  return $base;
195  }
196 
204  public function personallyIdentifiableTarget() {
205  return true;
206  }
207 }
208 
213 class_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 just to redirect the user to the translated version of a page,...
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:76
static newMainPage(MessageLocalizer $localizer=null)
Create a new Title for the Main Page.
Definition: Title.php:686
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:400
Service for resolving a wiki page redirect.