/**
  * Generates a form from the given request.
  * @param AuthenticationRequest[] $requests
  * @param string $action AuthManager action name
  * @param string|Message $msg
  * @param string $msgType
  * @return HTMLForm
  */
 protected function getAuthForm(array $requests, $action, $msg = '', $msgType = 'error')
 {
     global $wgSecureLogin, $wgLoginLanguageSelector;
     // FIXME merge this with parent
     if (isset($this->authForm)) {
         return $this->authForm;
     }
     $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
     // get basic form description from the auth logic
     $fieldInfo = AuthenticationRequest::mergeFieldInfo($requests);
     $fakeTemplate = $this->getFakeTemplate($msg, $msgType);
     $this->fakeTemplate = $fakeTemplate;
     // FIXME there should be a saner way to pass this to the hook
     // this will call onAuthChangeFormFields()
     $formDescriptor = static::fieldInfoToFormDescriptor($requests, $fieldInfo, $this->authAction);
     $this->postProcessFormDescriptor($formDescriptor);
     $context = $this->getContext();
     if ($context->getRequest() !== $this->getRequest()) {
         // We have overridden the request, need to make sure the form uses that too.
         $context = new DerivativeContext($this->getContext());
         $context->setRequest($this->getRequest());
     }
     $form = HTMLForm::factory('vform', $formDescriptor, $context);
     $form->addHiddenField('authAction', $this->authAction);
     if ($wgLoginLanguageSelector) {
         $form->addHiddenField('uselang', $this->mLanguage);
     }
     $form->addHiddenField('force', $this->securityLevel);
     $form->addHiddenField($this->getTokenName(), $this->getToken()->toString());
     if ($wgSecureLogin) {
         // If using HTTPS coming from HTTP, then the 'fromhttp' parameter must be preserved
         if (!$this->isSignup()) {
             $form->addHiddenField('wpForceHttps', (int) $this->mStickHTTPS);
             $form->addHiddenField('wpFromhttp', $usingHTTPS);
         }
     }
     // set properties of the form itself
     $form->setAction($this->getPageTitle()->getLocalURL($this->getReturnToQueryStringFragment()));
     $form->setName('userlogin' . ($this->isSignup() ? '2' : ''));
     if ($this->isSignup()) {
         $form->setId('userlogin2');
     }
     // add pre/post text
     // header used by ConfirmEdit, CondfirmAccount, Persona, WikimediaIncubator, SemanticSignup
     // should be above the error message but HTMLForm doesn't support that
     $form->addHeaderText($fakeTemplate->html('header'));
     // FIXME the old form used this for error/warning messages which does not play well with
     // HTMLForm (maybe it could with a subclass?); for now only display it for signups
     // (where the JS username validation needs it) and alway empty
     if ($this->isSignup()) {
         // used by the mediawiki.special.userlogin.signup.js module
         $statusAreaAttribs = ['id' => 'mw-createacct-status-area'];
         // $statusAreaAttribs += $msg ? [ 'class' => "{$msgType}box" ] : [ 'style' => 'display: none;' ];
         $form->addHeaderText(Html::element('div', $statusAreaAttribs));
     }
     // header used by MobileFrontend
     $form->addHeaderText($fakeTemplate->html('formheader'));
     // blank signup footer for site customization
     if ($this->isSignup() && $this->showExtraInformation()) {
         // Use signupend-https for HTTPS requests if it's not blank, signupend otherwise
         $signupendMsg = $this->msg('signupend');
         $signupendHttpsMsg = $this->msg('signupend-https');
         if (!$signupendMsg->isDisabled()) {
             $signupendText = $usingHTTPS && !$signupendHttpsMsg->isBlank() ? $signupendHttpsMsg->parse() : $signupendMsg->parse();
             $form->addPostText(Html::rawElement('div', ['id' => 'signupend'], $signupendText));
         }
     }
     // warning header for non-standard workflows (e.g. security reauthentication)
     if (!$this->isSignup() && $this->getUser()->isLoggedIn()) {
         $reauthMessage = $this->securityLevel ? 'userlogin-reauth' : 'userlogin-loggedin';
         $form->addHeaderText(Html::rawElement('div', ['class' => 'warningbox'], $this->msg($reauthMessage)->params($this->getUser()->getName())->parse()));
     }
     if (!$this->isSignup() && $this->showExtraInformation()) {
         $passwordReset = new PasswordReset($this->getConfig(), AuthManager::singleton());
         if ($passwordReset->isAllowed($this->getUser())) {
             $form->addFooterText(Html::rawElement('div', ['class' => 'mw-ui-vform-field mw-form-related-link-container'], Linker::link(SpecialPage::getTitleFor('PasswordReset'), $this->msg('userlogin-resetpassword-link')->escaped())));
         }
         // Don't show a "create account" link if the user can't.
         if ($this->showCreateAccountLink()) {
             // link to the other action
             $linkTitle = $this->getTitleFor($this->isSignup() ? 'Userlogin' : 'CreateAccount');
             $linkq = $this->getReturnToQueryStringFragment();
             // Pass any language selection on to the mode switch link
             if ($wgLoginLanguageSelector && $this->mLanguage) {
                 $linkq .= '&uselang=' . $this->mLanguage;
             }
             $createOrLoginHref = $linkTitle->getLocalURL($linkq);
             if ($this->getUser()->isLoggedIn()) {
                 $createOrLoginHtml = Html::rawElement('div', ['class' => 'mw-ui-vform-field'], Html::element('a', ['id' => 'mw-createaccount-join', 'href' => $createOrLoginHref, 'tabindex' => 100], $this->msg('userlogin-createanother')->escaped()));
             } else {
                 $createOrLoginHtml = Html::rawElement('div', ['id' => 'mw-createaccount-cta', 'class' => 'mw-ui-vform-field'], $this->msg('userlogin-noaccount')->escaped() . Html::element('a', ['id' => 'mw-createaccount-join', 'href' => $createOrLoginHref, 'class' => 'mw-ui-button', 'tabindex' => 100], $this->msg('userlogin-joinproject')->escaped()));
             }
             $form->addFooterText($createOrLoginHtml);
         }
     }
     $form->suppressDefaultSubmit();
     $this->authForm = $form;
     return $form;
 }
 /**
  * Format an array of AuthenticationRequests for return
  * @param AuthenticationRequest[] $reqs
  * @return array Will have a 'requests' key, and also 'fields' if $module's
  *  params include 'mergerequestfields'.
  */
 public function formatRequests(array $reqs)
 {
     $params = $this->module->extractRequestParams();
     $mergeFields = !empty($params['mergerequestfields']);
     $ret = ['requests' => []];
     foreach ($reqs as $req) {
         $describe = $req->describeCredentials();
         $reqInfo = ['id' => $req->getUniqueId(), 'metadata' => $req->getMetadata()];
         switch ($req->required) {
             case AuthenticationRequest::OPTIONAL:
                 $reqInfo['required'] = 'optional';
                 break;
             case AuthenticationRequest::REQUIRED:
                 $reqInfo['required'] = 'required';
                 break;
             case AuthenticationRequest::PRIMARY_REQUIRED:
                 $reqInfo['required'] = 'primary-required';
                 break;
         }
         $this->formatMessage($reqInfo, 'provider', $describe['provider']);
         $this->formatMessage($reqInfo, 'account', $describe['account']);
         if (!$mergeFields) {
             $reqInfo['fields'] = $this->formatFields((array) $req->getFieldInfo());
         }
         $ret['requests'][] = $reqInfo;
     }
     if ($mergeFields) {
         $fields = AuthenticationRequest::mergeFieldInfo($reqs);
         $ret['fields'] = $this->formatFields($fields);
     }
     return $ret;
 }
 /**
  * Generates a HTMLForm descriptor array from a set of authentication requests.
  * @param AuthenticationRequest[] $requests
  * @param string $action AuthManager action name (one of the AuthManager::ACTION_* constants)
  * @return array
  */
 protected function getAuthFormDescriptor($requests, $action)
 {
     $fieldInfo = AuthenticationRequest::mergeFieldInfo($requests);
     $formDescriptor = $this->fieldInfoToFormDescriptor($requests, $fieldInfo, $action);
     $this->addTabIndex($formDescriptor);
     return $formDescriptor;
 }
 /**
  * Generates a form from the given request.
  * @param AuthenticationRequest[] $requests
  * @param string $action AuthManager action name
  * @param string|Message $msg
  * @param string $msgType
  * @return HTMLForm
  */
 protected function getAuthForm(array $requests, $action, $msg = '', $msgType = 'error')
 {
     global $wgSecureLogin, $wgLoginLanguageSelector;
     // FIXME merge this with parent
     if (isset($this->authForm)) {
         return $this->authForm;
     }
     $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
     // get basic form description from the auth logic
     $fieldInfo = AuthenticationRequest::mergeFieldInfo($requests);
     $fakeTemplate = $this->getFakeTemplate($msg, $msgType);
     $this->fakeTemplate = $fakeTemplate;
     // FIXME there should be a saner way to pass this to the hook
     // this will call onAuthChangeFormFields()
     $formDescriptor = static::fieldInfoToFormDescriptor($requests, $fieldInfo, $this->authAction);
     $this->postProcessFormDescriptor($formDescriptor, $requests);
     $context = $this->getContext();
     if ($context->getRequest() !== $this->getRequest()) {
         // We have overridden the request, need to make sure the form uses that too.
         $context = new DerivativeContext($this->getContext());
         $context->setRequest($this->getRequest());
     }
     $form = HTMLForm::factory('vform', $formDescriptor, $context);
     $form->addHiddenField('authAction', $this->authAction);
     if ($wgLoginLanguageSelector) {
         $form->addHiddenField('uselang', $this->mLanguage);
     }
     $form->addHiddenField('force', $this->securityLevel);
     $form->addHiddenField($this->getTokenName(), $this->getToken()->toString());
     if ($wgSecureLogin) {
         // If using HTTPS coming from HTTP, then the 'fromhttp' parameter must be preserved
         if (!$this->isSignup()) {
             $form->addHiddenField('wpForceHttps', (int) $this->mStickHTTPS);
             $form->addHiddenField('wpFromhttp', $usingHTTPS);
         }
     }
     // set properties of the form itself
     $form->setAction($this->getPageTitle()->getLocalURL($this->getReturnToQueryStringFragment()));
     $form->setName('userlogin' . ($this->isSignup() ? '2' : ''));
     if ($this->isSignup()) {
         $form->setId('userlogin2');
     }
     $form->suppressDefaultSubmit();
     $this->authForm = $form;
     return $form;
 }