33 use Wikimedia\ScopedCallback;
55 private $reasonValidatorResult =
null;
78 abstract protected function successfulAction( $direct =
false, $extraMessages =
null );
90 parent::__construct( $name, $restriction );
96 protected function setRequest( array $data, $wasPosted =
null ) {
97 parent::setRequest( $data, $wasPosted );
98 $this->mLoadedRequest =
false;
104 private function loadRequestParameters() {
105 if ( $this->mLoadedRequest ) {
108 $this->mLoadedRequest =
true;
111 $this->mPosted = $request->wasPosted();
112 $this->mAction = $request->getRawVal(
'action' );
113 $this->mFromHTTP = $request->getBool(
'fromhttp',
false )
114 || $request->getBool(
'wpFromhttp',
false );
115 $this->mStickHTTPS = $this->
getConfig()->get( MainConfigNames::ForceHTTPS )
116 || ( !$this->mFromHTTP && $request->getProtocol() ===
'https' )
117 || $request->getBool(
'wpForceHttps',
false );
118 $this->mLanguage = $request->getText(
'uselang' );
119 $this->mReturnTo = $request->getVal(
'returnto',
'' );
120 $this->mReturnToQuery = $request->getVal(
'returntoquery',
'' );
129 $this->loadRequestParameters();
130 if ( $this->mLoaded ) {
133 $this->mLoaded =
true;
136 $securityLevel = $this->
getRequest()->getText(
'force' );
139 MediaWikiServices::getInstance()->
getAuthManager()->securitySensitiveOperationStatus(
147 $this->mToken = $request->getVal( $this->
getTokenName() );
150 $entryError = $this->
msg( $request->getVal(
'error',
'' ) );
151 $entryWarning = $this->
msg( $request->getVal(
'warning',
'' ) );
156 $this->
msg(
'loginreqlink' )->text(),
159 'returnto' => $this->mReturnTo,
160 'returntoquery' => $this->mReturnToQuery,
161 'uselang' => $this->mLanguage ?:
null,
162 'fromhttp' => $this->
getConfig()->
get( MainConfigNames::SecureLogin ) &&
163 $this->mFromHTTP ?
'1' :
null,
168 if ( $entryError->exists()
171 $this->mEntryErrorType =
'error';
172 $this->mEntryError = $entryError->rawParams( $loginreqlink )->parse();
174 } elseif ( $entryWarning->exists()
177 $this->mEntryErrorType =
'warning';
178 $this->mEntryError = $entryWarning->rawParams( $loginreqlink )->parse();
181 # 1. When switching accounts, it sucks to get automatically logged out
182 # 2. Do not return to PasswordReset after a successful password change
183 # but goto Wiki start page (Main_Page) instead ( T35997 )
185 if ( is_object( $returnToTitle )
186 && ( $returnToTitle->isSpecial(
'Userlogout' )
187 || $returnToTitle->isSpecial(
'PasswordReset' ) )
189 $this->mReturnTo =
'';
190 $this->mReturnToQuery =
'';
195 $params = parent::getPreservedParams( $withToken );
197 'returnto' => $this->mReturnTo ?:
null,
198 'returntoquery' => $this->mReturnToQuery ?:
null,
200 if ( $this->
getConfig()->
get( MainConfigNames::SecureLogin ) && !$this->
isSignup() ) {
201 $params[
'fromhttp'] = $this->mFromHTTP ?
'1' :
null;
208 $this->loadRequestParameters();
209 return parent::beforeExecute(
$subPage );
217 if ( $this->mPosted ) {
218 $time = microtime(
true );
219 $profilingScope =
new ScopedCallback(
function () use ( $time ) {
220 $time = microtime(
true ) - $time;
221 $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
222 $statsd->timing(
"timing.login.ui.{$this->authAction}", $time * 1000 );
226 $authManager = MediaWikiServices::getInstance()->getAuthManager();
227 $session = SessionManager::getGlobalSession();
234 $this->
getOutput()->disableClientCache();
241 if ( !$this->
isSignup() && !$authManager->canAuthenticateNow() ) {
242 if ( !$session->canSetUser() ) {
243 throw new ErrorPageError(
'cannotloginnow-title',
'cannotloginnow-text', [
244 $session->getProvider()->describe( $this->getLanguage() )
247 throw new ErrorPageError(
'cannotlogin-title',
'cannotlogin-text' );
248 } elseif ( $this->
isSignup() && !$authManager->canCreateAccounts() ) {
249 throw new ErrorPageError(
'cannotcreateaccount-title',
'cannotcreateaccount-text' );
270 if ( !$this->
isSignup() && !$this->mPosted && !$this->securityLevel &&
271 ( $this->mReturnTo !==
'' || $this->mReturnToQuery !==
'' ) &&
279 if ( $this->
getRequest()->getProtocol() !==
'https' ) {
283 ( $this->mEntryErrorType ===
'error' ?
'error'
284 :
'warning' ) => $this->mEntryError,
292 $this->
getOutput()->addVaryHeader(
'X-Forwarded-Proto' );
299 if ( str_starts_with( $url,
'https://' ) ) {
300 $this->mSecureLoginUrl = $url;
309 $this->
mainLoginForm( [],
'authpage-cannot-' . $this->authAction );
313 if ( $this->canBypassForm( $button_name ) ) {
316 if ( $button_name ) {
317 $this->
getRequest()->setVal( $button_name,
true );
323 if ( !$status || !$status->isGood() ) {
324 $this->
mainLoginForm( $this->authRequests, $status ? $status->getMessage() :
'',
'error' );
329 $response = $status->getValue();
333 switch ( $response->status ) {
334 case AuthenticationResponse::PASS:
336 $this->proxyAccountCreation = $this->
isSignup() && $this->
getUser()->isNamed();
340 !$this->proxyAccountCreation
341 && $response->loginRequest
342 && $authManager->canAuthenticateNow()
345 $response2 = $authManager->beginAuthentication( [ $response->loginRequest ],
347 if ( $response2->status !== AuthenticationResponse::PASS ) {
348 LoggerFactory::getInstance(
'login' )
349 ->error(
'Could not log in after account creation' );
355 if ( !$this->proxyAccountCreation ) {
362 case AuthenticationResponse::FAIL:
364 case AuthenticationResponse::RESTART:
365 unset( $this->authForm );
366 if ( $response->status === AuthenticationResponse::FAIL ) {
368 $messageType =
'error';
371 $messageType =
'warning';
373 $this->
logAuthResult(
false, $response->message ? $response->message->getKey() :
'-' );
375 $this->
mainLoginForm( $this->authRequests, $response->message, $messageType );
377 case AuthenticationResponse::REDIRECT:
378 unset( $this->authForm );
379 $this->
getOutput()->redirect( $response->redirectTarget );
381 case AuthenticationResponse::UI:
382 unset( $this->authForm );
383 $this->authAction = $this->
isSignup() ? AuthManager::ACTION_CREATE_CONTINUE
384 : AuthManager::ACTION_LOGIN_CONTINUE;
385 $this->authRequests = $response->neededRequests;
386 $this->
mainLoginForm( $response->neededRequests, $response->message, $response->messageType );
389 throw new LogicException(
'invalid AuthenticationResponse' );
406 private function canBypassForm( &$button_name ) {
411 $fields = AuthenticationRequest::mergeFieldInfo( $this->authRequests );
412 foreach ( $fields as $fieldname => $field ) {
413 if ( !isset( $field[
'type'] ) ) {
416 if ( !empty( $field[
'skippable'] ) ) {
419 if ( $field[
'type'] ===
'button' ) {
420 if ( $button_name !==
null ) {
424 $button_name = $fieldname;
426 } elseif ( $field[
'type'] !==
'null' ) {
443 $type,
$title, $msgname, $injected_html, $extraMessages
446 $out->setPageTitle(
$title );
450 if ( $extraMessages ) {
452 $out->addWikiTextAsInterface(
453 $extraMessages->getWikiText(
false,
false, $this->getLanguage() )
457 $out->addHTML( $injected_html );
460 $helper->showReturnToPage(
$type, $this->mReturnTo, $this->mReturnToQuery, $this->mStickHTTPS );
479 $type, $returnTo =
'', $returnToQuery =
'', $stickHTTPS =
false
482 $helper->showReturnToPage(
$type, $returnTo, $returnToQuery, $stickHTTPS );
494 if ( $context !== $localContext ) {
499 $user = $context->getRequest()->getSession()->getUser();
501 StubGlobalUser::setUser( $user );
502 $context->setUser( $user );
504 $wgLang = $context->getLanguage();
521 protected function mainLoginForm( array $requests, $msg =
'', $msgtype =
'error' ) {
529 $this->authForm =
null;
530 $requests = MediaWikiServices::getInstance()->getAuthManager()
531 ->getAuthenticationRequests( $this->authAction, $user );
535 $out->addModuleStyles( [
537 'mediawiki.ui.button',
538 'mediawiki.ui.checkbox',
539 'mediawiki.ui.input',
540 'mediawiki.special.userlogin.common.styles'
544 $out->addJsConfigVars(
'wgCreateacctImgcaptchaHelp',
545 $this->
msg(
'createacct-imgcaptcha-help' )->parse() );
548 $out->addModules(
'mediawiki.special.createaccount' );
549 $out->addModuleStyles( [
550 'mediawiki.special.userlogin.signup.styles'
554 $out->addModuleStyles( [
555 'mediawiki.special.userlogin.login.styles'
558 $out->disallowUserJs();
560 $form = $this->
getAuthForm( $requests, $this->authAction, $msg, $msgtype );
561 $form->prepareForm();
564 if ( $msg && $msgtype ===
'warning' ) {
565 $submitStatus->warning( $msg );
566 } elseif ( $msg && $msgtype ===
'error' ) {
567 $submitStatus->fatal( $msg );
573 $this->
getUser()->isRegistered() &&
575 $this->authAction !== AuthManager::ACTION_LOGIN_CONTINUE
577 $reauthMessage = $this->securityLevel ?
'userlogin-reauth' :
'userlogin-loggedin';
578 $submitStatus->warning( $reauthMessage, $this->
getUser()->
getName() );
581 $formHtml = $form->getHTML( $submitStatus );
594 [
'id' =>
'userloginprompt' ], $this->
msg(
'loginprompt' )->parseAsBlock() );
595 $languageLinks = $this->
getConfig()->get( MainConfigNames::LoginLanguageSelector )
597 $signupStartMsg = $this->
msg(
'signupstart' );
598 $signupStart = ( $this->
isSignup() && !$signupStartMsg->isDisabled() )
599 ?
Html::rawElement(
'div', [
'id' =>
'signupstart' ], $signupStartMsg->parseAsBlock() ) :
'';
600 if ( $languageLinks ) {
623 $benefitsContainer =
'';
631 for ( $benefitIdx = 1; $benefitIdx <= $benefitCount; $benefitIdx++ ) {
632 $headUnescaped = $this->
msg(
"createacct-benefit-head$benefitIdx" )->text();
633 $iconClass = $this->
msg(
"createacct-benefit-icon$benefitIdx" )->text();
634 $benefitList .=
Html::rawElement(
'div', [
'class' =>
"mw-number-text $iconClass" ],
636 $this->
msg(
"createacct-benefit-head$benefitIdx" )->escaped()
639 $this->
msg(
"createacct-benefit-body$benefitIdx" )->params( $headUnescaped )->escaped()
643 $benefitsContainer =
Html::rawElement(
'div', [
'class' =>
'mw-createacct-benefits-container' ],
645 .
Html::rawElement(
'div', [
'class' =>
'mw-createacct-benefits-list' ], $benefitList )
648 return $benefitsContainer;
659 protected function getAuthForm( array $requests, $action, $msg =
'', $msgType =
'error' ) {
662 if ( isset( $this->authForm ) ) {
663 return $this->authForm;
666 $usingHTTPS = $this->getRequest()->getProtocol() ===
'https';
669 $fieldInfo = AuthenticationRequest::mergeFieldInfo( $requests );
671 $formDescriptor = $this->fieldInfoToFormDescriptor( $requests, $fieldInfo, $this->authAction );
672 $this->postProcessFormDescriptor( $formDescriptor, $requests );
675 if ( $context->getRequest() !== $this->getRequest() ) {
678 $context->setRequest( $this->getRequest() );
682 $form->addHiddenField(
'authAction', $this->authAction );
683 if ( $this->mLanguage ) {
684 $form->addHiddenField(
'uselang', $this->mLanguage );
686 $form->addHiddenField(
'force', $this->securityLevel );
687 $form->addHiddenField( $this->getTokenName(), $this->getToken()->toString() );
688 $config = $this->getConfig();
689 if ( $config->get( MainConfigNames::SecureLogin ) &&
690 !$config->get( MainConfigNames::ForceHTTPS ) ) {
692 if ( !$this->isSignup() ) {
693 $form->addHiddenField(
'wpForceHttps', (
int)$this->mStickHTTPS );
694 $form->addHiddenField(
'wpFromhttp', $usingHTTPS );
699 $form->setAction( $this->getPageTitle()->getLocalURL( $this->getReturnToQueryStringFragment() ) );
700 $form->setName(
'userlogin' . ( $this->isSignup() ?
'2' :
'' ) );
701 if ( $this->isSignup() ) {
702 $form->setId(
'userlogin2' );
705 $form->suppressDefaultSubmit();
707 $this->authForm = $form;
714 array $requests, array $fieldInfo, array &$formDescriptor, $action
716 $formDescriptor = self::mergeDefaultFormDescriptor( $fieldInfo, $formDescriptor,
717 $this->getFieldDefinitions( $fieldInfo ) );
727 return $this->authAction !== $this->getContinueAction( $this->authAction )
728 && !$this->securityLevel;
737 $isLoggedIn = $this->
getUser()->isRegistered();
738 $continuePart = $this->isContinued() ?
'continue-' :
'';
739 $anotherPart = $isLoggedIn ?
'another-' :
'';
741 $expiration = $this->getRequest()->getSession()->getProvider()->getRememberUserDuration();
742 $expirationDays = ceil( $expiration / ( 3600 * 24 ) );
743 $secureLoginLink =
'';
744 if ( $this->mSecureLoginUrl ) {
746 'href' => $this->mSecureLoginUrl,
747 'class' =>
'mw-ui-flush-right mw-secure',
748 ], $this->msg(
'userlogin-signwithsecure' )->text() );
750 $usernameHelpLink =
'';
751 if ( !$this->msg(
'createacct-helpusername' )->isDisabled() ) {
753 'class' =>
'mw-ui-flush-right',
754 ], $this->msg(
'createacct-helpusername' )->parse() );
757 if ( $this->isSignup() ) {
758 $config = $this->getConfig();
759 $hideIf = isset( $fieldInfo[
'mailpassword'] ) ? [
'hide-if' => [
'===',
'mailpassword',
'1' ] ] : [];
760 $fieldDefinitions = [
766 'default' =>
Html::element(
'div', [
'id' =>
'mw-createacct-status-area' ] ),
770 'label-raw' => $this->msg(
'userlogin-yourname' )->escaped() . $usernameHelpLink,
772 'placeholder-message' => $isLoggedIn ?
'createacct-another-username-ph'
773 :
'userlogin-yourname-ph',
778 'label-message' =>
'createaccountmail',
779 'name' =>
'wpCreateaccountMail',
780 'id' =>
'wpCreateaccountMail',
783 'id' =>
'wpPassword2',
784 'autocomplete' =>
'new-password',
785 'placeholder-message' =>
'createacct-yourpassword-ph',
786 'help-message' =>
'createacct-useuniquepass',
790 'type' =>
'password',
791 'label-message' =>
'createacct-yourpasswordagain',
793 'cssclass' =>
'loginPassword',
795 'autocomplete' =>
'new-password',
796 'validation-callback' =>
function ( $value, $alldata ) {
797 if ( empty( $alldata[
'mailpassword'] ) && !empty( $alldata[
'password'] ) ) {
799 return $this->msg(
'htmlform-required' );
800 } elseif ( $value !== $alldata[
'password'] ) {
801 return $this->msg(
'badretype' );
806 'placeholder-message' =>
'createacct-yourpasswordagain-ph',
810 'label-message' => $config->get( MainConfigNames::EmailConfirmToEdit )
811 ?
'createacct-emailrequired' :
'createacct-emailoptional',
813 'cssclass' =>
'loginText',
816 'autocomplete' =>
'email',
818 'required' => $config->get( MainConfigNames::EmailConfirmToEdit ),
819 'validation-callback' =>
function ( $value, $alldata ) {
823 $this->getConfig()->get( MainConfigNames::EmailConfirmToEdit )
827 return $this->msg(
'noemailtitle' );
828 } elseif ( !$value && !empty( $alldata[
'mailpassword'] ) ) {
830 return $this->msg(
'noemailcreate' );
832 return $this->msg(
'invalidemailaddress' );
833 } elseif ( is_string( $value ) && strlen( $value ) > 255 ) {
834 return $this->msg(
'changeemail-maxlength' );
841 'placeholder-message' =>
'createacct-' . $anotherPart .
'email-ph',
845 'help-message' => $isLoggedIn ?
'createacct-another-realname-tip'
846 :
'prefs-help-realname',
847 'label-message' =>
'createacct-realname',
848 'cssclass' =>
'loginText',
850 'id' =>
'wpRealName',
851 'autocomplete' =>
'name',
856 'label-message' =>
'createacct-reason',
857 'cssclass' =>
'loginText',
860 'validation-callback' =>
function ( $value, $alldata ) {
864 if ( $this->reasonValidatorResult !==
null ) {
865 return $this->reasonValidatorResult;
867 $this->reasonValidatorResult =
true;
868 $authManager = MediaWikiServices::getInstance()->getAuthManager();
869 if ( !$authManager->getAuthenticationSessionData(
'reason-retry',
false ) ) {
870 $authManager->setAuthenticationSessionData(
'reason-retry',
true );
871 $this->reasonValidatorResult = $this->msg(
'createacct-reason-confirm' );
873 return $this->reasonValidatorResult;
877 'placeholder-message' =>
'createacct-reason-ph',
887 'default' => $this->msg(
'createacct-' . $anotherPart . $continuePart .
889 'name' =>
'wpCreateaccount',
890 'id' =>
'wpCreateaccount',
894 if ( !$this->msg(
'createacct-username-help' )->isDisabled() ) {
895 $fieldDefinitions[
'username'][
'help-message'] =
'createacct-username-help';
901 $passwordRequest = AuthenticationRequest::getRequestByClass( $this->authRequests,
902 PasswordAuthenticationRequest::class );
903 $changePassword = $passwordRequest && $passwordRequest->action == AuthManager::ACTION_CHANGE;
904 $fieldDefinitions = [
907 'label-raw' => $this->msg(
'userlogin-yourname' )->escaped() . $secureLoginLink,
909 'placeholder-message' =>
'userlogin-yourname-ph',
910 ] + ( $changePassword ? [
913 'baseField' =>
'password',
916 'cssclass' =>
'mw-htmlform-hidden-field',
921 'autocomplete' =>
'new-password',
922 'placeholder-message' =>
'createacct-yourpassword-ph',
923 'help-message' =>
'createacct-useuniquepass',
925 'id' =>
'wpPassword1',
926 'autocomplete' =>
'current-password',
927 'placeholder-message' =>
'userlogin-yourpassword-ph',
931 'type' =>
'password',
932 'autocomplete' =>
'new-password',
933 'placeholder-message' =>
'createacct-yourpasswordagain-ph',
939 'cssclass' =>
'mw-userlogin-rememberme',
940 'name' =>
'wpRemember',
941 'label-message' => $this->msg(
'userlogin-remembermypassword' )
942 ->numParams( $expirationDays ),
943 'id' =>
'wpRemember',
951 'default' => $this->msg(
'pt-login-' . $continuePart .
'button' )->text(),
952 'id' =>
'wpLoginAttempt',
958 'cssclass' =>
'mw-form-related-link-container mw-userlogin-help',
963 ->inContentLanguage()
965 ], $this->msg(
'userlogin-helplink2' )->text() ),
976 $fieldDefinitions[
'username'] += [
979 'cssclass' =>
'loginText',
981 'autocomplete' =>
'username',
984 $fieldDefinitions[
'password'] += [
985 'type' =>
'password',
987 'name' =>
'wpPassword',
988 'cssclass' =>
'loginPassword',
993 if ( $this->mEntryError ) {
995 if ( $this->mEntryErrorType ===
'error' ) {
997 } elseif ( $this->mEntryErrorType ===
'warning' ) {
1000 $fieldDefinitions[
'entryError'] = [
1002 'default' => $defaultHtml,
1008 if ( $this->isSignup() && $this->
getUser()->isTemp() ) {
1009 $fieldDefinitions[
'tempWarning'] = [
1012 $this->msg(
'createacct-temp-warning' )->parse()
1019 if ( !$this->showExtraInformation() ) {
1020 unset( $fieldDefinitions[
'linkcontainer'], $fieldDefinitions[
'signupend'] );
1022 if ( $this->isSignup() && $this->showExtraInformation() ) {
1025 $signupendMsg = $this->msg(
'signupend' );
1026 $signupendHttpsMsg = $this->msg(
'signupend-https' );
1027 if ( !$signupendMsg->isDisabled() ) {
1028 $usingHTTPS = $this->getRequest()->getProtocol() ===
'https';
1029 $signupendText = ( $usingHTTPS && !$signupendHttpsMsg->isBlank() )
1030 ? $signupendHttpsMsg->parse() : $signupendMsg->parse();
1031 $fieldDefinitions[
'signupend'] = [
1034 'default' =>
Html::rawElement(
'div', [
'id' =>
'signupend' ], $signupendText ),
1039 if ( !$this->isSignup() && $this->showExtraInformation() ) {
1040 $passwordReset = MediaWikiServices::getInstance()->getPasswordReset();
1041 if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) {
1042 $fieldDefinitions[
'passwordReset'] = [
1045 'cssclass' =>
'mw-form-related-link-container',
1046 'default' => $this->getLinkRenderer()->makeLink(
1048 $this->msg(
'userlogin-resetpassword-link' )->text()
1055 if ( $this->showCreateAccountLink() ) {
1057 $linkTitle = $this->getTitleFor( $this->isSignup() ?
'Userlogin' :
'CreateAccount' );
1058 $linkq = $this->getReturnToQueryStringFragment();
1060 if ( $this->mLanguage ) {
1061 $linkq .=
'&uselang=' . urlencode( $this->mLanguage );
1063 $isLoggedIn = $this->
getUser()->isRegistered()
1064 && !$this->
getUser()->isTemp();
1066 $fieldDefinitions[
'createOrLogin'] = [
1069 'linkQuery' => $linkq,
1070 'default' =>
function ( $params ) use ( $isLoggedIn, $linkTitle ) {
1072 [
'id' =>
'mw-createaccount' . ( !$isLoggedIn ?
'-cta' :
'' ),
1073 'class' => ( $isLoggedIn ?
'mw-form-related-link-container' :
'mw-ui-vform-field' ) ],
1074 ( $isLoggedIn ?
'' : $this->msg(
'userlogin-noaccount' )->escaped() )
1077 'id' =>
'mw-createaccount-join' . ( $isLoggedIn ?
'-loggedin' :
'' ),
1078 'href' => $linkTitle->getLocalURL( $params[
'linkQuery'] ),
1079 'class' => ( $isLoggedIn ?
'' :
'mw-ui-button' ),
1083 $isLoggedIn ?
'userlogin-createanother' :
'userlogin-joinproject'
1093 return $fieldDefinitions;
1106 $config = $this->getConfig();
1107 return $config->get( MainConfigNames::DisableCookieCheck ) || (
1108 $config->get(
'InitialSessionId' ) &&
1109 $this->getRequest()->getSession()->getId() === (string)$config->get(
'InitialSessionId' )
1120 if ( $this->mReturnTo !==
'' ) {
1121 $returnto =
'returnto=' .
wfUrlencode( $this->mReturnTo );
1122 if ( $this->mReturnToQuery !==
'' ) {
1123 $returnto .=
'&returntoquery=' .
wfUrlencode( $this->mReturnToQuery );
1134 private function showCreateAccountLink() {
1135 return $this->isSignup() ||
1136 $this->
getContext()->getAuthority()->isAllowed(
'createaccount' );
1140 return $this->isSignup() ?
'wpCreateaccountToken' :
'wpLoginToken';
1150 $msg = $this->msg(
'loginlanguagelinks' )->inContentLanguage();
1151 if ( $msg->isBlank() ) {
1154 $langs = explode(
"\n", $msg->text() );
1156 foreach ( $langs as
$lang ) {
1158 $parts = explode(
'|',
$lang );
1159 if ( count( $parts ) >= 2 ) {
1160 $links[] = $this->makeLanguageSelectorLink( $parts[0], trim( $parts[1] ) );
1164 return count( $links ) > 0 ? $this->msg(
'loginlanguagelabel' )->rawParams(
1165 $this->getLanguage()->pipeList( $links ) )->escaped() :
'';
1177 if ( $this->getLanguage()->getCode() ==
$lang ) {
1179 return htmlspecialchars( $text );
1181 $query = [
'uselang' =>
$lang ];
1182 if ( $this->mReturnTo !==
'' ) {
1183 $query[
'returnto'] = $this->mReturnTo;
1184 $query[
'returntoquery'] = $this->mReturnToQuery;
1188 $targetLanguage = MediaWikiServices::getInstance()->getLanguageFactory()
1189 ->getLanguage(
$lang );
1190 $attr[
'lang'] = $attr[
'hreflang'] = $targetLanguage->getHtmlCode();
1192 return $this->getLinkRenderer()->makeKnownLink(
1193 $this->getPageTitle(),
1211 isset( $formDescriptor[
'username'] ) &&
1212 !isset( $formDescriptor[
'username'][
'default'] ) &&
1216 if ( $user->isRegistered() && !$user->isTemp() ) {
1217 $formDescriptor[
'username'][
'default'] = $user->getName();
1219 $formDescriptor[
'username'][
'default'] =
1220 $this->getRequest()->getSession()->suggestLoginUsername();
1226 if ( !$this->needsSubmitButton( $requests ) ) {
1227 unset( $formDescriptor[
'createaccount'], $formDescriptor[
'loginattempt'] );
1230 if ( !$this->isSignup() ) {
1234 isset( $formDescriptor[
'username'] )
1235 && empty( $formDescriptor[
'username'][
'default'] )
1236 && !$this->getRequest()->getCheck(
'wpName' )
1238 $formDescriptor[
'username'][
'autofocus'] =
true;
1239 } elseif ( isset( $formDescriptor[
'password'] ) ) {
1240 $formDescriptor[
'password'][
'autofocus'] =
true;
1244 $this->addTabIndex( $formDescriptor );
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode) $wgLang
A special page subclass for authentication-related special pages.
getContinueAction( $action)
Gets the _CONTINUE version of an action.
isActionAllowed( $action)
Checks whether AuthManager is ready to perform the action.
loadAuth( $subPage, $authAction=null, $reset=false)
Load or initialize $authAction, $authRequests and $subPage.
getDefaultAction( $subPage)
Get the default action for this special page, if none is given via URL/POST data.
string $subPage
Subpage of the special page.
isContinued()
Returns true if this is not the first step of the authentication.
getRequest()
Get the WebRequest being used for this instance.
trySubmit()
Attempts to do an authentication step with the submitted data.
getToken()
Returns the CSRF token.
An IContextSource implementation which will inherit context from another source but allow individual ...
An error page which can definitely be safely rendered using the OutputPage.
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
static warningBox( $html, $className='')
Return a warning box.
static errorBox( $html, $heading='', $className='')
Return an error box.
Helper functions for the login form that need to be shared with other special pages (such as CentralA...
static getValidErrorMessages()
Returns an array of all valid error messages.
Holds shared logic for login and account creation pages.
mainLoginForm(array $requests, $msg='', $msgtype='error')
getPreservedParams( $withToken=false)
Returns URL query parameters which can be used to reload the page (or leave and return) while preserv...
logAuthResult( $success, $status=null)
Logs to the authmanager-stats channel.
onAuthChangeFormFields(array $requests, array $fieldInfo, array &$formDescriptor, $action)
Change the form descriptor that determines how a field will look in the authentication form....
setSessionUserForCurrentRequest()
Replace some globals to make sure the fact that the user has just been logged in is reflected in the ...
getBenefitsContainerHtml()
The HTML to be shown in the "benefits to signing in / creating an account" section of the signup/logi...
showSuccessPage( $type, $title, $msgname, $injected_html, $extraMessages)
Show the success page.
getFieldDefinitions(array $fieldInfo)
Create a HTMLForm descriptor for the core login fields.
getReturnToQueryStringFragment()
Returns a string that can be appended to the URL (without encoding) to preserve the return target.
User $targetUser
FIXME another flag for passing data.
successfulAction( $direct=false, $extraMessages=null)
showExtraInformation()
Show extra information such as password recovery information, link from login to signup,...
getPageHtml( $formHtml)
Add page elements which are outside the form.
hasSessionCookie()
Check if a session cookie is present.
__construct( $name, $restriction='')
getAuthForm(array $requests, $action, $msg='', $msgType='error')
Generates a form from the given request.
getTokenName()
Returns the name of the CSRF token (under which it should be found in the POST or GET data).
makeLanguageSelectorLink( $text, $lang)
Create a language selector link for a particular language Links back to this page preserving type and...
bool $proxyAccountCreation
True if the user if creating an account for someone else.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
postProcessFormDescriptor(&$formDescriptor, $requests)
setRequest(array $data, $wasPosted=null)
Override the POST data, GET data from the real request is preserved.
showReturnToPage( $type, $returnTo='', $returnToQuery='', $stickHTTPS=false)
Add a "return to" link or redirect to it.
makeLanguageSelector()
Produce a bar of links which allow the user to select another language during login/registration but ...
load( $subPage)
Load data from request.
A class containing constants representing the names of configuration variables.
static getMain()
Get the RequestContext object associated with the main request.
static validateEmail( $addr)
Does a string look like an e-mail address?
static makeInternalOrExternalUrl( $name)
If url string starts with http, consider as external URL, else internal.
setContext( $context)
Sets the context this SpecialPage is executed in.
getName()
Get the name of this Special Page.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getPageTitle( $subpage=false)
Get a self-referential title object.
getFullTitle()
Return the full title, including $par.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
static newGood( $value=null)
Factory function for good results.
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
static newFromName( $name, $validate='valid')
$wgUseMediaWikiUIEverywhere
Config variable stub for the UseMediaWikiUIEverywhere setting, for use by phpdoc and IDEs.
if(!isset( $args[0])) $lang