35 use Wikimedia\ScopedCallback;
58 private $reasonValidatorResult =
null;
81 abstract protected function successfulAction( $direct =
false, $extraMessages =
null );
93 parent::__construct( $name, $restriction );
99 protected function setRequest( array $data, $wasPosted =
null ) {
100 parent::setRequest( $data, $wasPosted );
101 $this->mLoadedRequest =
false;
107 private function loadRequestParameters() {
108 if ( $this->mLoadedRequest ) {
111 $this->mLoadedRequest =
true;
114 $this->mPosted = $request->wasPosted();
115 $this->mAction = $request->getRawVal(
'action' );
116 $this->mFromHTTP = $request->getBool(
'fromhttp',
false )
117 || $request->getBool(
'wpFromhttp',
false );
118 $this->mStickHTTPS = $this->
getConfig()->get( MainConfigNames::ForceHTTPS )
119 || ( !$this->mFromHTTP && $request->getProtocol() ===
'https' )
120 || $request->getBool(
'wpForceHttps',
false );
121 $this->mLanguage = $request->getText(
'uselang' );
122 $this->mVariant = $request->getText(
'variant' );
123 $this->mReturnTo = $request->getVal(
'returnto',
'' );
124 $this->mReturnToQuery = $request->getVal(
'returntoquery',
'' );
133 $this->loadRequestParameters();
134 if ( $this->mLoaded ) {
137 $this->mLoaded =
true;
140 $securityLevel = $this->
getRequest()->getText(
'force' );
143 MediaWikiServices::getInstance()->
getAuthManager()->securitySensitiveOperationStatus(
151 $this->mToken = $request->getVal( $this->
getTokenName() );
154 $entryError = $this->
msg( $request->getVal(
'error',
'' ) );
155 $entryWarning = $this->
msg( $request->getVal(
'warning',
'' ) );
160 $this->
msg(
'loginreqlink' )->text(),
163 'returnto' => $this->mReturnTo,
164 'returntoquery' => $this->mReturnToQuery,
165 'uselang' => $this->mLanguage ?:
null,
166 'variant' => $this->mVariant ?:
null,
167 'fromhttp' => $this->
getConfig()->
get( MainConfigNames::SecureLogin ) &&
168 $this->mFromHTTP ?
'1' :
null,
173 if ( $entryError->exists()
176 $this->mEntryErrorType =
'error';
177 $this->mEntryError = $entryError->rawParams( $loginreqlink )->parse();
179 } elseif ( $entryWarning->exists()
182 $this->mEntryErrorType =
'warning';
183 $this->mEntryError = $entryWarning->rawParams( $loginreqlink )->parse();
186 # 1. When switching accounts, it sucks to get automatically logged out
187 # 2. Do not return to PasswordReset after a successful password change
188 # but goto Wiki start page (Main_Page) instead ( T35997 )
189 $returnToTitle = Title::newFromText( $this->mReturnTo );
190 if ( is_object( $returnToTitle )
191 && ( $returnToTitle->isSpecial(
'Userlogout' )
192 || $returnToTitle->isSpecial(
'PasswordReset' ) )
194 $this->mReturnTo =
'';
195 $this->mReturnToQuery =
'';
200 $params = parent::getPreservedParams( $withToken );
202 'returnto' => $this->mReturnTo ?:
null,
203 'returntoquery' => $this->mReturnToQuery ?:
null,
205 if ( $this->
getConfig()->
get( MainConfigNames::SecureLogin ) && !$this->
isSignup() ) {
206 $params[
'fromhttp'] = $this->mFromHTTP ?
'1' :
null;
213 $this->loadRequestParameters();
214 return parent::beforeExecute(
$subPage );
222 if ( $this->mPosted ) {
223 $time = microtime(
true );
224 $profilingScope =
new ScopedCallback(
function () use ( $time ) {
225 $time = microtime(
true ) - $time;
226 $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
227 $statsd->timing(
"timing.login.ui.{$this->authAction}", $time * 1000 );
231 $authManager = MediaWikiServices::getInstance()->getAuthManager();
232 $session = SessionManager::getGlobalSession();
239 $this->
getOutput()->disableClientCache();
246 if ( !$this->
isSignup() && !$authManager->canAuthenticateNow() ) {
247 if ( !$session->canSetUser() ) {
248 throw new ErrorPageError(
'cannotloginnow-title',
'cannotloginnow-text', [
249 $session->getProvider()->describe( $this->getLanguage() )
252 throw new ErrorPageError(
'cannotlogin-title',
'cannotlogin-text' );
253 } elseif ( $this->
isSignup() && !$authManager->canCreateAccounts() ) {
254 throw new ErrorPageError(
'cannotcreateaccount-title',
'cannotcreateaccount-text' );
275 if ( !$this->
isSignup() && !$this->mPosted && !$this->securityLevel &&
276 ( $this->mReturnTo !==
'' || $this->mReturnToQuery !==
'' ) &&
284 if ( $this->
getRequest()->getProtocol() !==
'https' ) {
288 ( $this->mEntryErrorType ===
'error' ?
'error'
289 :
'warning' ) => $this->mEntryError,
297 $this->
getOutput()->addVaryHeader(
'X-Forwarded-Proto' );
304 if ( str_starts_with( $url,
'https://' ) ) {
305 $this->mSecureLoginUrl = $url;
314 $this->
mainLoginForm( [],
'authpage-cannot-' . $this->authAction );
318 if ( $this->canBypassForm( $button_name ) ) {
321 if ( $button_name ) {
322 $this->
getRequest()->setVal( $button_name,
true );
328 if ( !$status || !$status->isGood() ) {
329 $this->
mainLoginForm( $this->authRequests, $status ? $status->getMessage() :
'',
'error' );
334 $response = $status->getValue();
338 switch ( $response->status ) {
339 case AuthenticationResponse::PASS:
341 $this->proxyAccountCreation = $this->
isSignup() && $this->
getUser()->isNamed();
345 !$this->proxyAccountCreation
346 && $response->loginRequest
347 && $authManager->canAuthenticateNow()
350 $response2 = $authManager->beginAuthentication( [ $response->loginRequest ],
352 if ( $response2->status !== AuthenticationResponse::PASS ) {
353 LoggerFactory::getInstance(
'login' )
354 ->error(
'Could not log in after account creation' );
360 if ( !$this->proxyAccountCreation ) {
367 case AuthenticationResponse::FAIL:
369 case AuthenticationResponse::RESTART:
370 unset( $this->authForm );
371 if ( $response->status === AuthenticationResponse::FAIL ) {
373 $messageType =
'error';
376 $messageType =
'warning';
378 $this->
logAuthResult(
false, $response->message ? $response->message->getKey() :
'-' );
380 $this->
mainLoginForm( $this->authRequests, $response->message, $messageType );
382 case AuthenticationResponse::REDIRECT:
383 unset( $this->authForm );
384 $this->
getOutput()->redirect( $response->redirectTarget );
386 case AuthenticationResponse::UI:
387 unset( $this->authForm );
388 $this->authAction = $this->
isSignup() ? AuthManager::ACTION_CREATE_CONTINUE
389 : AuthManager::ACTION_LOGIN_CONTINUE;
390 $this->authRequests = $response->neededRequests;
391 $this->
mainLoginForm( $response->neededRequests, $response->message, $response->messageType );
394 throw new LogicException(
'invalid AuthenticationResponse' );
411 private function canBypassForm( &$button_name ) {
416 $fields = AuthenticationRequest::mergeFieldInfo( $this->authRequests );
417 foreach ( $fields as $fieldname => $field ) {
418 if ( !isset( $field[
'type'] ) ) {
421 if ( !empty( $field[
'skippable'] ) ) {
424 if ( $field[
'type'] ===
'button' ) {
425 if ( $button_name !==
null ) {
429 $button_name = $fieldname;
431 } elseif ( $field[
'type'] !==
'null' ) {
448 $type,
$title, $msgname, $injected_html, $extraMessages
451 $out->setPageTitle(
$title );
455 if ( $extraMessages ) {
457 $out->addWikiTextAsInterface(
458 $extraMessages->getWikiText(
false,
false, $this->getLanguage() )
462 $out->addHTML( $injected_html );
465 $helper->showReturnToPage(
$type, $this->mReturnTo, $this->mReturnToQuery, $this->mStickHTTPS );
484 $type, $returnTo =
'', $returnToQuery =
'', $stickHTTPS =
false
487 $helper->showReturnToPage(
$type, $returnTo, $returnToQuery, $stickHTTPS );
499 if ( $context !== $localContext ) {
504 $user = $context->getRequest()->getSession()->getUser();
506 StubGlobalUser::setUser( $user );
507 $context->setUser( $user );
509 $wgLang = $context->getLanguage();
526 protected function mainLoginForm( array $requests, $msg =
'', $msgtype =
'error' ) {
534 $this->authForm =
null;
535 $requests = MediaWikiServices::getInstance()->getAuthManager()
536 ->getAuthenticationRequests( $this->authAction, $user );
540 $out->addModuleStyles( [
542 'mediawiki.ui.button',
543 'mediawiki.ui.checkbox',
544 'mediawiki.ui.input',
545 'mediawiki.special.userlogin.common.styles'
549 $out->addJsConfigVars(
'wgCreateacctImgcaptchaHelp',
550 $this->
msg(
'createacct-imgcaptcha-help' )->parse() );
553 $out->addModules(
'mediawiki.special.createaccount' );
554 $out->addModuleStyles( [
555 'mediawiki.special.userlogin.signup.styles'
559 $out->addModuleStyles( [
560 'mediawiki.special.userlogin.login.styles'
563 $out->disallowUserJs();
565 $form = $this->
getAuthForm( $requests, $this->authAction, $msg, $msgtype );
566 $form->prepareForm();
569 if ( $msg && $msgtype ===
'warning' ) {
570 $submitStatus->warning( $msg );
571 } elseif ( $msg && $msgtype ===
'error' ) {
572 $submitStatus->fatal( $msg );
578 $this->
getUser()->isRegistered() &&
580 $this->authAction !== AuthManager::ACTION_LOGIN_CONTINUE
582 $reauthMessage = $this->securityLevel ?
'userlogin-reauth' :
'userlogin-loggedin';
583 $submitStatus->warning( $reauthMessage, $this->
getUser()->
getName() );
586 $formHtml = $form->getHTML( $submitStatus );
598 $loginPrompt = $this->
isSignup() ?
'' : Html::rawElement(
'div',
599 [
'id' =>
'userloginprompt' ], $this->
msg(
'loginprompt' )->parseAsBlock() );
600 $languageLinks = $this->
getConfig()->get( MainConfigNames::LoginLanguageSelector )
602 $signupStartMsg = $this->
msg(
'signupstart' );
603 $signupStart = ( $this->
isSignup() && !$signupStartMsg->isDisabled() )
604 ? Html::rawElement(
'div', [
'id' =>
'signupstart' ], $signupStartMsg->parseAsBlock() ) :
'';
605 if ( $languageLinks ) {
606 $languageLinks = Html::rawElement(
'div', [
'id' =>
'languagelinks' ],
607 Html::rawElement(
'p', [], $languageLinks )
611 $formBlock = Html::rawElement(
'div', [
'id' =>
'userloginForm' ], $formHtml );
612 $formAndBenefits = $formBlock;
614 $benefitsContainerHtml =
null;
620 'beforeForm' =>
false,
623 $benefitsContainerHtml, $info, $options
625 if ( $benefitsContainerHtml ===
null ) {
628 $formAndBenefits = $options[
'beforeForm']
629 ? ( $benefitsContainerHtml . $formBlock )
630 : ( $formBlock . $benefitsContainerHtml );
633 return Html::rawElement(
'div', [
'class' =>
'mw-ui-container' ],
649 $benefitsContainer =
'';
657 for ( $benefitIdx = 1; $benefitIdx <= $benefitCount; $benefitIdx++ ) {
658 $headUnescaped = $this->
msg(
"createacct-benefit-head$benefitIdx" )->text();
659 $iconClass = $this->
msg(
"createacct-benefit-icon$benefitIdx" )->text();
660 $benefitList .= Html::rawElement(
'div', [
'class' =>
"mw-number-text $iconClass" ],
661 Html::rawElement(
'h3', [],
662 $this->
msg(
"createacct-benefit-head$benefitIdx" )->escaped()
664 . Html::rawElement(
'p', [],
665 $this->
msg(
"createacct-benefit-body$benefitIdx" )->params( $headUnescaped )->escaped()
669 $benefitsContainer = Html::rawElement(
'div', [
'class' =>
'mw-createacct-benefits-container' ],
670 Html::rawElement(
'h2', [], $this->
msg(
'createacct-benefit-heading' )->escaped() )
671 . Html::rawElement(
'div', [
'class' =>
'mw-createacct-benefits-list' ], $benefitList )
674 return $benefitsContainer;
685 protected function getAuthForm( array $requests, $action, $msg =
'', $msgType =
'error' ) {
688 if ( isset( $this->authForm ) ) {
689 return $this->authForm;
692 $usingHTTPS = $this->
getRequest()->getProtocol() ===
'https';
695 $fieldInfo = AuthenticationRequest::mergeFieldInfo( $requests );
697 $formDescriptor = $this->fieldInfoToFormDescriptor( $requests, $fieldInfo, $this->authAction );
698 $this->postProcessFormDescriptor( $formDescriptor, $requests );
701 if ( $context->getRequest() !== $this->getRequest() ) {
708 $form->addHiddenField(
'authAction', $this->authAction );
709 if ( $this->mLanguage ) {
710 $form->addHiddenField(
'uselang', $this->mLanguage );
712 if ( $this->mVariant ) {
713 $form->addHiddenField(
'variant', $this->mVariant );
715 $form->addHiddenField(
'force', $this->securityLevel );
716 $form->addHiddenField( $this->getTokenName(), $this->getToken()->toString() );
717 $config = $this->getConfig();
718 if ( $config->get( MainConfigNames::SecureLogin ) &&
719 !$config->get( MainConfigNames::ForceHTTPS ) ) {
721 if ( !$this->isSignup() ) {
722 $form->addHiddenField(
'wpForceHttps', (
int)$this->mStickHTTPS );
723 $form->addHiddenField(
'wpFromhttp', $usingHTTPS );
728 $form->setAction( $this->getPageTitle()->getLocalURL( $this->getReturnToQueryStringFragment() ) );
729 $form->setName(
'userlogin' . ( $this->isSignup() ?
'2' :
'' ) );
730 if ( $this->isSignup() ) {
731 $form->setId(
'userlogin2' );
734 $form->suppressDefaultSubmit();
736 $this->authForm = $form;
743 array $requests, array $fieldInfo, array &$formDescriptor, $action
745 $formDescriptor = self::mergeDefaultFormDescriptor( $fieldInfo, $formDescriptor,
746 $this->getFieldDefinitions( $fieldInfo ) );
756 return $this->authAction !== $this->getContinueAction( $this->authAction )
757 && !$this->securityLevel;
766 $isLoggedIn = $this->
getUser()->isRegistered();
767 $continuePart = $this->isContinued() ?
'continue-' :
'';
768 $anotherPart = $isLoggedIn ?
'another-' :
'';
770 $expiration = $this->
getRequest()->getSession()->getProvider()->getRememberUserDuration();
771 $expirationDays = ceil( $expiration / ( 3600 * 24 ) );
772 $secureLoginLink =
'';
773 if ( $this->mSecureLoginUrl ) {
774 $secureLoginLink = Html::element(
'a', [
775 'href' => $this->mSecureLoginUrl,
776 'class' =>
'mw-ui-flush-right mw-secure',
777 ], $this->msg(
'userlogin-signwithsecure' )->text() );
779 $usernameHelpLink =
'';
780 if ( !$this->msg(
'createacct-helpusername' )->isDisabled() ) {
781 $usernameHelpLink = Html::rawElement(
'span', [
782 'class' =>
'mw-ui-flush-right',
783 ], $this->msg(
'createacct-helpusername' )->parse() );
786 if ( $this->isSignup() ) {
787 $config = $this->getConfig();
788 $hideIf = isset( $fieldInfo[
'mailpassword'] ) ? [
'hide-if' => [
'===',
'mailpassword',
'1' ] ] : [];
789 $fieldDefinitions = [
795 'default' => Html::element(
'div', [
'id' =>
'mw-createacct-status-area' ] ),
799 'label-raw' => $this->msg(
'userlogin-yourname' )->escaped() . $usernameHelpLink,
801 'placeholder-message' => $isLoggedIn ?
'createacct-another-username-ph'
802 :
'userlogin-yourname-ph',
807 'label-message' =>
'createaccountmail',
808 'name' =>
'wpCreateaccountMail',
809 'id' =>
'wpCreateaccountMail',
812 'id' =>
'wpPassword2',
813 'autocomplete' =>
'new-password',
814 'placeholder-message' =>
'createacct-yourpassword-ph',
815 'help-message' =>
'createacct-useuniquepass',
819 'type' =>
'password',
820 'label-message' =>
'createacct-yourpasswordagain',
822 'cssclass' =>
'loginPassword',
824 'autocomplete' =>
'new-password',
825 'validation-callback' =>
function ( $value, $alldata ) {
826 if ( empty( $alldata[
'mailpassword'] ) && !empty( $alldata[
'password'] ) ) {
828 return $this->msg(
'htmlform-required' );
829 } elseif ( $value !== $alldata[
'password'] ) {
830 return $this->msg(
'badretype' );
835 'placeholder-message' =>
'createacct-yourpasswordagain-ph',
839 'label-message' => $config->get( MainConfigNames::EmailConfirmToEdit )
840 ?
'createacct-emailrequired' :
'createacct-emailoptional',
842 'cssclass' =>
'loginText',
845 'autocomplete' =>
'email',
847 'required' => $config->get( MainConfigNames::EmailConfirmToEdit ),
848 'validation-callback' =>
function ( $value, $alldata ) {
852 $this->getConfig()->get( MainConfigNames::EmailConfirmToEdit )
856 return $this->msg(
'noemailtitle' );
857 } elseif ( !$value && !empty( $alldata[
'mailpassword'] ) ) {
859 return $this->msg(
'noemailcreate' );
861 return $this->msg(
'invalidemailaddress' );
862 } elseif ( is_string( $value ) && strlen( $value ) > 255 ) {
863 return $this->msg(
'changeemail-maxlength' );
870 'placeholder-message' =>
'createacct-' . $anotherPart .
'email-ph',
874 'help-message' => $isLoggedIn ?
'createacct-another-realname-tip'
875 :
'prefs-help-realname',
876 'label-message' =>
'createacct-realname',
877 'cssclass' =>
'loginText',
879 'id' =>
'wpRealName',
880 'autocomplete' =>
'name',
885 'label-message' =>
'createacct-reason',
886 'cssclass' =>
'loginText',
889 'validation-callback' =>
function ( $value, $alldata ) {
893 if ( $this->reasonValidatorResult !==
null ) {
894 return $this->reasonValidatorResult;
896 $this->reasonValidatorResult =
true;
897 $authManager = MediaWikiServices::getInstance()->getAuthManager();
898 if ( !$authManager->getAuthenticationSessionData(
'reason-retry',
false ) ) {
899 $authManager->setAuthenticationSessionData(
'reason-retry',
true );
900 $this->reasonValidatorResult = $this->msg(
'createacct-reason-confirm' );
902 return $this->reasonValidatorResult;
906 'placeholder-message' =>
'createacct-reason-ph',
916 'default' => $this->msg(
'createacct-' . $anotherPart . $continuePart .
918 'name' =>
'wpCreateaccount',
919 'id' =>
'wpCreateaccount',
923 if ( !$this->msg(
'createacct-username-help' )->isDisabled() ) {
924 $fieldDefinitions[
'username'][
'help-message'] =
'createacct-username-help';
930 $passwordRequest = AuthenticationRequest::getRequestByClass( $this->authRequests,
931 PasswordAuthenticationRequest::class );
932 $changePassword = $passwordRequest && $passwordRequest->action == AuthManager::ACTION_CHANGE;
933 $fieldDefinitions = [
936 'label-raw' => $this->msg(
'userlogin-yourname' )->escaped() . $secureLoginLink,
938 'placeholder-message' =>
'userlogin-yourname-ph',
939 ] + ( $changePassword ? [
942 'baseField' =>
'password',
945 'cssclass' =>
'mw-htmlform-hidden-field',
950 'autocomplete' =>
'new-password',
951 'placeholder-message' =>
'createacct-yourpassword-ph',
952 'help-message' =>
'createacct-useuniquepass',
954 'id' =>
'wpPassword1',
955 'autocomplete' =>
'current-password',
956 'placeholder-message' =>
'userlogin-yourpassword-ph',
960 'type' =>
'password',
961 'autocomplete' =>
'new-password',
962 'placeholder-message' =>
'createacct-yourpasswordagain-ph',
968 'cssclass' =>
'mw-userlogin-rememberme',
969 'name' =>
'wpRemember',
970 'label-message' => $this->msg(
'userlogin-remembermypassword' )
971 ->numParams( $expirationDays ),
972 'id' =>
'wpRemember',
980 'default' => $this->msg(
'pt-login-' . $continuePart .
'button' )->text(),
981 'id' =>
'wpLoginAttempt',
987 'cssclass' =>
'mw-form-related-link-container mw-userlogin-help',
990 'default' => Html::element(
'a', [
992 ->inContentLanguage()
994 ], $this->msg(
'userlogin-helplink2' )->text() ),
1005 $fieldDefinitions[
'username'] += [
1008 'cssclass' =>
'loginText',
1010 'autocomplete' =>
'username',
1013 $fieldDefinitions[
'password'] += [
1014 'type' =>
'password',
1016 'name' =>
'wpPassword',
1017 'cssclass' =>
'loginPassword',
1022 if ( $this->mEntryError ) {
1024 if ( $this->mEntryErrorType ===
'error' ) {
1025 $defaultHtml = Html::errorBox( $this->mEntryError );
1026 } elseif ( $this->mEntryErrorType ===
'warning' ) {
1027 $defaultHtml = Html::warningBox( $this->mEntryError );
1029 $fieldDefinitions[
'entryError'] = [
1031 'default' => $defaultHtml,
1037 if ( $this->isSignup() && $this->
getUser()->isTemp() ) {
1038 $fieldDefinitions[
'tempWarning'] = [
1040 'default' => Html::warningBox(
1041 $this->msg(
'createacct-temp-warning' )->parse()
1048 if ( !$this->showExtraInformation() ) {
1049 unset( $fieldDefinitions[
'linkcontainer'], $fieldDefinitions[
'signupend'] );
1051 if ( $this->isSignup() && $this->showExtraInformation() ) {
1054 $signupendMsg = $this->msg(
'signupend' );
1055 $signupendHttpsMsg = $this->msg(
'signupend-https' );
1056 if ( !$signupendMsg->isDisabled() ) {
1057 $usingHTTPS = $this->
getRequest()->getProtocol() ===
'https';
1058 $signupendText = ( $usingHTTPS && !$signupendHttpsMsg->isBlank() )
1059 ? $signupendHttpsMsg->parse() : $signupendMsg->parse();
1060 $fieldDefinitions[
'signupend'] = [
1063 'default' => Html::rawElement(
'div', [
'id' =>
'signupend' ], $signupendText ),
1068 if ( !$this->isSignup() && $this->showExtraInformation() ) {
1069 $passwordReset = MediaWikiServices::getInstance()->getPasswordReset();
1070 if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) {
1071 $fieldDefinitions[
'passwordReset'] = [
1074 'cssclass' =>
'mw-form-related-link-container',
1075 'default' => $this->getLinkRenderer()->makeLink(
1077 $this->msg(
'userlogin-resetpassword-link' )->text()
1084 if ( $this->showCreateAccountLink() ) {
1086 $linkTitle = $this->getTitleFor( $this->isSignup() ?
'Userlogin' :
'CreateAccount' );
1087 $linkq = $this->getReturnToQueryStringFragment();
1089 if ( $this->mLanguage ) {
1090 $linkq .=
'&uselang=' . urlencode( $this->mLanguage );
1092 if ( $this->mVariant ) {
1093 $linkq .=
'&variant=' . urlencode( $this->mVariant );
1095 $isLoggedIn = $this->
getUser()->isRegistered()
1096 && !$this->
getUser()->isTemp();
1098 $fieldDefinitions[
'createOrLogin'] = [
1101 'linkQuery' => $linkq,
1102 'default' =>
function ( $params ) use ( $isLoggedIn, $linkTitle ) {
1103 return Html::rawElement(
'div',
1104 [
'id' =>
'mw-createaccount' . ( !$isLoggedIn ?
'-cta' :
'' ),
1105 'class' => ( $isLoggedIn ?
'mw-form-related-link-container' :
'mw-ui-vform-field' ) ],
1106 ( $isLoggedIn ?
'' : $this->msg(
'userlogin-noaccount' )->escaped() )
1107 . Html::element(
'a',
1109 'id' =>
'mw-createaccount-join' . ( $isLoggedIn ?
'-loggedin' :
'' ),
1110 'href' => $linkTitle->getLocalURL( $params[
'linkQuery'] ),
1111 'class' => ( $isLoggedIn ?
'' :
'mw-ui-button' ),
1115 $isLoggedIn ?
'userlogin-createanother' :
'userlogin-joinproject'
1125 return $fieldDefinitions;
1138 $config = $this->getConfig();
1139 return $config->get( MainConfigNames::DisableCookieCheck ) || (
1140 $config->get(
'InitialSessionId' ) &&
1141 $this->
getRequest()->getSession()->getId() === (string)$config->get(
'InitialSessionId' )
1152 if ( $this->mReturnTo !==
'' ) {
1153 $returnto =
'returnto=' .
wfUrlencode( $this->mReturnTo );
1154 if ( $this->mReturnToQuery !==
'' ) {
1155 $returnto .=
'&returntoquery=' .
wfUrlencode( $this->mReturnToQuery );
1166 private function showCreateAccountLink() {
1167 return $this->isSignup() ||
1168 $this->
getContext()->getAuthority()->isAllowed(
'createaccount' );
1172 return $this->isSignup() ?
'wpCreateaccountToken' :
'wpLoginToken';
1182 $msg = $this->msg(
'loginlanguagelinks' )->inContentLanguage();
1183 if ( $msg->isBlank() ) {
1186 $langs = explode(
"\n", $msg->text() );
1188 foreach ( $langs as
$lang ) {
1190 $parts = explode(
'|',
$lang );
1191 if ( count( $parts ) >= 2 ) {
1192 $links[] = $this->makeLanguageSelectorLink( $parts[0], trim( $parts[1] ) );
1196 return count( $links ) > 0 ? $this->msg(
'loginlanguagelabel' )->rawParams(
1197 $this->getLanguage()->pipeList( $links ) )->escaped() :
'';
1209 if ( $this->getLanguage()->getCode() ==
$lang ) {
1211 return htmlspecialchars( $text );
1213 $query = [
'uselang' =>
$lang ];
1214 if ( $this->mVariant ) {
1215 $query[
'variant'] = $this->mVariant;
1217 if ( $this->mReturnTo !==
'' ) {
1218 $query[
'returnto'] = $this->mReturnTo;
1219 $query[
'returntoquery'] = $this->mReturnToQuery;
1223 $targetLanguage = MediaWikiServices::getInstance()->getLanguageFactory()
1224 ->getLanguage(
$lang );
1225 $attr[
'lang'] = $attr[
'hreflang'] = $targetLanguage->getHtmlCode();
1227 return $this->getLinkRenderer()->makeKnownLink(
1228 $this->getPageTitle(),
1246 isset( $formDescriptor[
'username'] ) &&
1247 !isset( $formDescriptor[
'username'][
'default'] ) &&
1251 if ( $user->isRegistered() && !$user->isTemp() ) {
1252 $formDescriptor[
'username'][
'default'] = $user->getName();
1254 $formDescriptor[
'username'][
'default'] =
1255 $this->
getRequest()->getSession()->suggestLoginUsername();
1261 if ( !$this->needsSubmitButton( $requests ) ) {
1262 unset( $formDescriptor[
'createaccount'], $formDescriptor[
'loginattempt'] );
1265 if ( !$this->isSignup() ) {
1269 isset( $formDescriptor[
'username'] )
1270 && empty( $formDescriptor[
'username'][
'default'] )
1271 && !$this->
getRequest()->getCheck(
'wpName' )
1273 $formDescriptor[
'username'][
'autofocus'] =
true;
1274 } elseif ( isset( $formDescriptor[
'password'] ) ) {
1275 $formDescriptor[
'password'][
'autofocus'] =
true;
1279 $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.
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 newFromName( $name, $validate='valid')
$wgUseMediaWikiUIEverywhere
Config variable stub for the UseMediaWikiUIEverywhere setting, for use by phpdoc and IDEs.
if(!isset( $args[0])) $lang