MediaWiki  REL1_22
SpecialChangeEmail.php
Go to the documentation of this file.
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 }