MediaWiki  REL1_23
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         $this->requireLogin( 'changeemail-no-info' );
00079 
00080         if ( $request->wasPosted() && $request->getBool( 'wpCancel' ) ) {
00081             $this->doReturnTo();
00082 
00083             return;
00084         }
00085 
00086         $this->checkReadOnly();
00087         $this->checkPermissions();
00088 
00089         // This could also let someone check the current email address, so
00090         // require both permissions.
00091         if ( !$user->isAllowed( 'viewmyprivateinfo' ) ) {
00092             throw new PermissionsError( 'viewmyprivateinfo' );
00093         }
00094 
00095         $this->mPassword = $request->getVal( 'wpPassword' );
00096         $this->mNewEmail = $request->getVal( 'wpNewEmail' );
00097 
00098         if ( $request->wasPosted()
00099             && $user->matchEditToken( $request->getVal( 'token' ) )
00100         ) {
00101             $info = $this->attemptChange( $user, $this->mPassword, $this->mNewEmail );
00102             if ( $info === true ) {
00103                 $this->doReturnTo();
00104             } elseif ( $info === 'eauth' ) {
00105                 # Notify user that a confirmation email has been sent...
00106                 $out->wrapWikiMsg( "<div class='error' style='clear: both;'>\n$1\n</div>",
00107                     'eauthentsent', $user->getName() );
00108                 $this->doReturnTo( 'soft' ); // just show the link to go back
00109                 return; // skip form
00110             }
00111         }
00112 
00113         $this->showForm();
00114     }
00115 
00119     protected function doReturnTo( $type = 'hard' ) {
00120         $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) );
00121         if ( !$titleObj instanceof Title ) {
00122             $titleObj = Title::newMainPage();
00123         }
00124         if ( $type == 'hard' ) {
00125             $this->getOutput()->redirect( $titleObj->getFullURL() );
00126         } else {
00127             $this->getOutput()->addReturnTo( $titleObj );
00128         }
00129     }
00130 
00134     protected function error( $msg ) {
00135         $this->getOutput()->wrapWikiMsg( "<p class='error'>\n$1\n</p>", $msg );
00136     }
00137 
00138     protected function showForm() {
00139         global $wgRequirePasswordforEmailChange;
00140         $user = $this->getUser();
00141 
00142         $oldEmailText = $user->getEmail()
00143             ? $user->getEmail()
00144             : $this->msg( 'changeemail-none' )->text();
00145 
00146         $this->getOutput()->addHTML(
00147             Xml::fieldset( $this->msg( 'changeemail-header' )->text() ) .
00148                 Xml::openElement( 'form',
00149                     array(
00150                         'method' => 'post',
00151                         'action' => $this->getPageTitle()->getLocalURL(),
00152                         'id' => 'mw-changeemail-form' ) ) . "\n" .
00153                 Html::hidden( 'token', $user->getEditToken() ) . "\n" .
00154                 Html::hidden( 'returnto', $this->getRequest()->getVal( 'returnto' ) ) . "\n" .
00155                 $this->msg( 'changeemail-text' )->parseAsBlock() . "\n" .
00156                 Xml::openElement( 'table', array( 'id' => 'mw-changeemail-table' ) ) . "\n"
00157         );
00158         $items = array(
00159             array( 'wpName', 'username', 'text', $user->getName() ),
00160             array( 'wpOldEmail', 'changeemail-oldemail', 'text', $oldEmailText ),
00161             array( 'wpNewEmail', 'changeemail-newemail', 'email', $this->mNewEmail ),
00162         );
00163         if ( $wgRequirePasswordforEmailChange ) {
00164             $items[] = array( 'wpPassword', 'changeemail-password', 'password', $this->mPassword );
00165         }
00166 
00167         $this->getOutput()->addHTML(
00168             $this->pretty( $items ) .
00169                 "\n" .
00170                 "<tr>\n" .
00171                 "<td></td>\n" .
00172                 '<td class="mw-input">' .
00173                 Xml::submitButton( $this->msg( 'changeemail-submit' )->text() ) .
00174                 Xml::submitButton( $this->msg( 'changeemail-cancel' )->text(), array( 'name' => 'wpCancel' ) ) .
00175                 "</td>\n" .
00176                 "</tr>\n" .
00177                 Xml::closeElement( 'table' ) .
00178                 Xml::closeElement( 'form' ) .
00179                 Xml::closeElement( 'fieldset' ) . "\n"
00180         );
00181     }
00182 
00187     protected function pretty( $fields ) {
00188         $out = '';
00189         foreach ( $fields as $list ) {
00190             list( $name, $label, $type, $value ) = $list;
00191             if ( $type == 'text' ) {
00192                 $field = htmlspecialchars( $value );
00193             } else {
00194                 $attribs = array( 'id' => $name );
00195                 if ( $name == 'wpPassword' ) {
00196                     $attribs[] = 'autofocus';
00197                 }
00198                 $field = Html::input( $name, $value, $type, $attribs );
00199             }
00200             $out .= "<tr>\n";
00201             $out .= "\t<td class='mw-label'>";
00202             if ( $type != 'text' ) {
00203                 $out .= Xml::label( $this->msg( $label )->text(), $name );
00204             } else {
00205                 $out .= $this->msg( $label )->escaped();
00206             }
00207             $out .= "</td>\n";
00208             $out .= "\t<td class='mw-input'>";
00209             $out .= $field;
00210             $out .= "</td>\n";
00211             $out .= "</tr>";
00212         }
00213 
00214         return $out;
00215     }
00216 
00223     protected function attemptChange( User $user, $pass, $newaddr ) {
00224         global $wgAuth, $wgPasswordAttemptThrottle;
00225 
00226         if ( $newaddr != '' && !Sanitizer::validateEmail( $newaddr ) ) {
00227             $this->error( 'invalidemailaddress' );
00228 
00229             return false;
00230         }
00231 
00232         $throttleCount = LoginForm::incLoginThrottle( $user->getName() );
00233         if ( $throttleCount === true ) {
00234             $lang = $this->getLanguage();
00235             $this->error( array( 'changeemail-throttled', $lang->formatDuration( $wgPasswordAttemptThrottle['seconds'] ) ) );
00236 
00237             return false;
00238         }
00239 
00240         global $wgRequirePasswordforEmailChange;
00241         if ( $wgRequirePasswordforEmailChange && !$user->checkTemporaryPassword( $pass ) && !$user->checkPassword( $pass ) ) {
00242             $this->error( 'wrongpassword' );
00243 
00244             return false;
00245         }
00246 
00247         if ( $throttleCount ) {
00248             LoginForm::clearLoginThrottle( $user->getName() );
00249         }
00250 
00251         $oldaddr = $user->getEmail();
00252         $status = $user->setEmailWithConfirmation( $newaddr );
00253         if ( !$status->isGood() ) {
00254             $this->getOutput()->addHTML(
00255                 '<p class="error">' .
00256                     $this->getOutput()->parseInline( $status->getWikiText( 'mailerror' ) ) .
00257                     '</p>' );
00258 
00259             return false;
00260         }
00261 
00262         wfRunHooks( 'PrefsEmailAudit', array( $user, $oldaddr, $newaddr ) );
00263 
00264         $user->saveSettings();
00265 
00266         $wgAuth->updateExternalDB( $user );
00267 
00268         return $status->value;
00269     }
00270 
00271     protected function getGroupName() {
00272         return 'users';
00273     }
00274 }