MediaWiki 1.40.4
SpecialConfirmEmail.php
Go to the documentation of this file.
1<?php
26use Wikimedia\ScopedCallback;
27
37
39 private $userFactory;
40
44 public function __construct( UserFactory $userFactory ) {
45 parent::__construct( 'Confirmemail', 'editmyprivateinfo' );
46
47 $this->userFactory = $userFactory;
48 }
49
50 public function doesWrites() {
51 return true;
52 }
53
62 public function execute( $code ) {
63 // Ignore things like primary queries/connections on GET requests.
64 // It's very convenient to just allow formless link usage.
65 $trxProfiler = Profiler::instance()->getTransactionProfiler();
66
67 $this->setHeaders();
68 $this->checkReadOnly();
69 $this->checkPermissions();
70
71 // This could also let someone check the current email address, so
72 // require both permissions.
73 if ( !$this->getAuthority()->isAllowed( 'viewmyprivateinfo' ) ) {
74 throw new PermissionsError( 'viewmyprivateinfo' );
75 }
76
77 if ( $code === null || $code === '' ) {
78 $this->requireLogin( 'confirmemail_needlogin' );
79 if ( Sanitizer::validateEmail( $this->getUser()->getEmail() ) ) {
80 $this->showRequestForm();
81 } else {
82 $this->getOutput()->addWikiMsg( 'confirmemail_noemail' );
83 }
84 } else {
85 $scope = $trxProfiler->silenceForScope( $trxProfiler::EXPECTATION_REPLICAS_ONLY );
86 $this->attemptConfirm( $code );
87 ScopedCallback::consume( $scope );
88 }
89 }
90
94 private function showRequestForm() {
95 $user = $this->getUser();
96 $out = $this->getOutput();
97
98 if ( !$user->isEmailConfirmed() ) {
99 $descriptor = [];
100 if ( $user->isEmailConfirmationPending() ) {
101 $descriptor += [
102 'pending' => [
103 'type' => 'info',
104 'raw' => true,
105 'default' => "<div class=\"error mw-confirmemail-pending\">\n" .
106 $this->msg( 'confirmemail_pending' )->escaped() .
107 "\n</div>",
108 ],
109 ];
110 }
111
112 $out->addWikiMsg( 'confirmemail_text' );
113 $form = HTMLForm::factory( 'ooui', $descriptor, $this->getContext() );
114 $form
115 ->setAction( $this->getPageTitle()->getLocalURL() )
116 ->setSubmitTextMsg( 'confirmemail_send' )
117 ->setSubmitCallback( [ $this, 'submitSend' ] );
118
119 $retval = $form->show();
120
121 if ( $retval === true ) {
122 // should never happen, but if so, don't let the user without any message
123 $out->addWikiMsg( 'confirmemail_sent' );
124 } elseif ( $retval instanceof Status && $retval->isGood() ) {
125 $out->addWikiTextAsInterface( $retval->getValue() );
126 }
127 } else {
128 // date and time are separate parameters to facilitate localisation.
129 // $time is kept for backward compat reasons.
130 // 'emailauthenticated' is also used in SpecialPreferences.php
131 $lang = $this->getLanguage();
132 $emailAuthenticated = $user->getEmailAuthenticationTimestamp();
133 $time = $lang->userTimeAndDate( $emailAuthenticated, $user );
134 $d = $lang->userDate( $emailAuthenticated, $user );
135 $t = $lang->userTime( $emailAuthenticated, $user );
136 $out->addWikiMsg( 'emailauthenticated', $time, $d, $t );
137 }
138 }
139
145 public function submitSend() {
146 $status = $this->getUser()->sendConfirmationMail();
147 if ( $status->isGood() ) {
148 return Status::newGood( $this->msg( 'confirmemail_sent' )->text() );
149 } else {
150 return Status::newFatal( new RawMessage(
151 $status->getWikiText( 'confirmemail_sendfailed', false, $this->getLanguage() )
152 ) );
153 }
154 }
155
162 private function attemptConfirm( $code ) {
163 $user = $this->userFactory->newFromConfirmationCode(
164 $code,
165 UserFactory::READ_LATEST
166 );
167
168 if ( !is_object( $user ) ) {
169 $this->getOutput()->addWikiMsg( 'confirmemail_invalid' );
170
171 return;
172 }
173
174 // rate limit email confirmations
175 if ( $user->pingLimiter( 'confirmemail' ) ) {
176 $this->getOutput()->addWikiMsg( 'actionthrottledtext' );
177
178 return;
179 }
180
181 $userLatest = $user->getInstanceForUpdate();
182 $userLatest->confirmEmail();
183 $userLatest->saveSettings();
184 $message = $this->getUser()->isRegistered() ? 'confirmemail_loggedin' : 'confirmemail_success';
185 $this->getOutput()->addWikiMsg( $message );
186
187 if ( !$this->getUser()->isRegistered() ) {
188 $title = SpecialPage::getTitleFor( 'Userlogin' );
189 $this->getOutput()->returnToMain( true, $title );
190 }
191 }
192}
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition HTMLForm.php:352
Variant of the Message class.
Creates User objects.
Show an error when a user tries to do something they do not have the necessary permissions for.
Special page allows users to request email confirmation message, and handles processing of the confir...
doesWrites()
Indicates whether this special page may perform database writes.
execute( $code)
Main execution point.
__construct(UserFactory $userFactory)
submitSend()
Callback for HTMLForm send confirmation mail.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
requireLogin( $reasonMsg='exception-nologin-text', $titleMsg='exception-nologin')
If the user is not logged in, throws UserNotLoggedIn error.
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.
getAuthority()
Shortcut to get the Authority executing this instance.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getPageTitle( $subpage=false)
Get a self-referential title object.
getLanguage()
Shortcut to get user's language.
isGood()
Returns whether the operation completed and didn't have any error or warnings.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:46
Shortcut to construct a special page which is unlisted by default.
if(!isset( $args[0])) $lang