MediaWiki
REL1_22
|
00001 <?php 00029 class SpecialChangeEmail extends UnlistedSpecialPage { 00030 00035 protected $mPassword; 00036 00041 protected $mNewEmail; 00042 00043 public function __construct() { 00044 parent::__construct( 'ChangeEmail', 'editmyprivateinfo' ); 00045 } 00046 00050 function isListed() { 00051 global $wgAuth; 00052 00053 return $wgAuth->allowPropChange( 'emailaddress' ); 00054 } 00055 00059 function execute( $par ) { 00060 global $wgAuth; 00061 00062 $this->setHeaders(); 00063 $this->outputHeader(); 00064 00065 $out = $this->getOutput(); 00066 $out->disallowUserJs(); 00067 $out->addModules( 'mediawiki.special.changeemail' ); 00068 00069 if ( !$wgAuth->allowPropChange( 'emailaddress' ) ) { 00070 $this->error( 'cannotchangeemail' ); 00071 00072 return; 00073 } 00074 00075 $user = $this->getUser(); 00076 $request = $this->getRequest(); 00077 00078 if ( !$request->wasPosted() && !$user->isLoggedIn() ) { 00079 $this->error( 'changeemail-no-info' ); 00080 00081 return; 00082 } 00083 00084 if ( $request->wasPosted() && $request->getBool( 'wpCancel' ) ) { 00085 $this->doReturnTo(); 00086 00087 return; 00088 } 00089 00090 $this->checkReadOnly(); 00091 $this->checkPermissions(); 00092 00093 // This could also let someone check the current email address, so 00094 // require both permissions. 00095 if ( !$this->getUser()->isAllowed( 'viewmyprivateinfo' ) ) { 00096 throw new PermissionsError( 'viewmyprivateinfo' ); 00097 } 00098 00099 $this->mPassword = $request->getVal( 'wpPassword' ); 00100 $this->mNewEmail = $request->getVal( 'wpNewEmail' ); 00101 00102 if ( $request->wasPosted() 00103 && $user->matchEditToken( $request->getVal( 'token' ) ) 00104 ) { 00105 $info = $this->attemptChange( $user, $this->mPassword, $this->mNewEmail ); 00106 if ( $info === true ) { 00107 $this->doReturnTo(); 00108 } elseif ( $info === 'eauth' ) { 00109 # Notify user that a confirmation email has been sent... 00110 $out->wrapWikiMsg( "<div class='error' style='clear: both;'>\n$1\n</div>", 00111 'eauthentsent', $user->getName() ); 00112 $this->doReturnTo( 'soft' ); // just show the link to go back 00113 return; // skip form 00114 } 00115 } 00116 00117 $this->showForm(); 00118 } 00119 00123 protected function doReturnTo( $type = 'hard' ) { 00124 $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) ); 00125 if ( !$titleObj instanceof Title ) { 00126 $titleObj = Title::newMainPage(); 00127 } 00128 if ( $type == 'hard' ) { 00129 $this->getOutput()->redirect( $titleObj->getFullURL() ); 00130 } else { 00131 $this->getOutput()->addReturnTo( $titleObj ); 00132 } 00133 } 00134 00138 protected function error( $msg ) { 00139 $this->getOutput()->wrapWikiMsg( "<p class='error'>\n$1\n</p>", $msg ); 00140 } 00141 00142 protected function showForm() { 00143 global $wgRequirePasswordforEmailChange; 00144 $user = $this->getUser(); 00145 00146 $oldEmailText = $user->getEmail() 00147 ? $user->getEmail() 00148 : $this->msg( 'changeemail-none' )->text(); 00149 00150 $this->getOutput()->addHTML( 00151 Xml::fieldset( $this->msg( 'changeemail-header' )->text() ) . 00152 Xml::openElement( 'form', 00153 array( 00154 'method' => 'post', 00155 'action' => $this->getTitle()->getLocalURL(), 00156 'id' => 'mw-changeemail-form' ) ) . "\n" . 00157 Html::hidden( 'token', $user->getEditToken() ) . "\n" . 00158 Html::hidden( 'returnto', $this->getRequest()->getVal( 'returnto' ) ) . "\n" . 00159 $this->msg( 'changeemail-text' )->parseAsBlock() . "\n" . 00160 Xml::openElement( 'table', array( 'id' => 'mw-changeemail-table' ) ) . "\n" 00161 ); 00162 $items = array( 00163 array( 'wpName', 'username', 'text', $user->getName() ), 00164 array( 'wpOldEmail', 'changeemail-oldemail', 'text', $oldEmailText ), 00165 array( 'wpNewEmail', 'changeemail-newemail', 'email', $this->mNewEmail ), 00166 ); 00167 if ( $wgRequirePasswordforEmailChange ) { 00168 $items[] = array( 'wpPassword', 'changeemail-password', 'password', $this->mPassword ); 00169 } 00170 00171 $this->getOutput()->addHTML( 00172 $this->pretty( $items ) . 00173 "\n" . 00174 "<tr>\n" . 00175 "<td></td>\n" . 00176 '<td class="mw-input">' . 00177 Xml::submitButton( $this->msg( 'changeemail-submit' )->text() ) . 00178 Xml::submitButton( $this->msg( 'changeemail-cancel' )->text(), array( 'name' => 'wpCancel' ) ) . 00179 "</td>\n" . 00180 "</tr>\n" . 00181 Xml::closeElement( 'table' ) . 00182 Xml::closeElement( 'form' ) . 00183 Xml::closeElement( 'fieldset' ) . "\n" 00184 ); 00185 } 00186 00191 protected function pretty( $fields ) { 00192 $out = ''; 00193 foreach ( $fields as $list ) { 00194 list( $name, $label, $type, $value ) = $list; 00195 if ( $type == 'text' ) { 00196 $field = htmlspecialchars( $value ); 00197 } else { 00198 $attribs = array( 'id' => $name ); 00199 if ( $name == 'wpPassword' ) { 00200 $attribs[] = 'autofocus'; 00201 } 00202 $field = Html::input( $name, $value, $type, $attribs ); 00203 } 00204 $out .= "<tr>\n"; 00205 $out .= "\t<td class='mw-label'>"; 00206 if ( $type != 'text' ) { 00207 $out .= Xml::label( $this->msg( $label )->text(), $name ); 00208 } else { 00209 $out .= $this->msg( $label )->escaped(); 00210 } 00211 $out .= "</td>\n"; 00212 $out .= "\t<td class='mw-input'>"; 00213 $out .= $field; 00214 $out .= "</td>\n"; 00215 $out .= "</tr>"; 00216 } 00217 00218 return $out; 00219 } 00220 00227 protected function attemptChange( User $user, $pass, $newaddr ) { 00228 global $wgAuth, $wgPasswordAttemptThrottle; 00229 00230 if ( $newaddr != '' && !Sanitizer::validateEmail( $newaddr ) ) { 00231 $this->error( 'invalidemailaddress' ); 00232 00233 return false; 00234 } 00235 00236 $throttleCount = LoginForm::incLoginThrottle( $user->getName() ); 00237 if ( $throttleCount === true ) { 00238 $lang = $this->getLanguage(); 00239 $this->error( array( 'login-throttled', $lang->formatDuration( $wgPasswordAttemptThrottle['seconds'] ) ) ); 00240 00241 return false; 00242 } 00243 00244 global $wgRequirePasswordforEmailChange; 00245 if ( $wgRequirePasswordforEmailChange && !$user->checkTemporaryPassword( $pass ) && !$user->checkPassword( $pass ) ) { 00246 $this->error( 'wrongpassword' ); 00247 00248 return false; 00249 } 00250 00251 if ( $throttleCount ) { 00252 LoginForm::clearLoginThrottle( $user->getName() ); 00253 } 00254 00255 $oldaddr = $user->getEmail(); 00256 $status = $user->setEmailWithConfirmation( $newaddr ); 00257 if ( !$status->isGood() ) { 00258 $this->getOutput()->addHTML( 00259 '<p class="error">' . 00260 $this->getOutput()->parseInline( $status->getWikiText( 'mailerror' ) ) . 00261 '</p>' ); 00262 00263 return false; 00264 } 00265 00266 wfRunHooks( 'PrefsEmailAudit', array( $user, $oldaddr, $newaddr ) ); 00267 00268 $user->saveSettings(); 00269 00270 $wgAuth->updateExternalDB( $user ); 00271 00272 return $status->value; 00273 } 00274 00275 protected function getGroupName() { 00276 return 'users'; 00277 } 00278 }