MediaWiki
REL1_19
|
00001 <?php 00029 class SpecialEmailUser extends UnlistedSpecialPage { 00030 protected $mTarget; 00031 00032 public function __construct() { 00033 parent::__construct( 'Emailuser' ); 00034 } 00035 00036 protected function getFormFields() { 00037 return array( 00038 'From' => array( 00039 'type' => 'info', 00040 'raw' => 1, 00041 'default' => Linker::link( 00042 $this->getUser()->getUserPage(), 00043 htmlspecialchars( $this->getUser()->getName() ) 00044 ), 00045 'label-message' => 'emailfrom', 00046 'id' => 'mw-emailuser-sender', 00047 ), 00048 'To' => array( 00049 'type' => 'info', 00050 'raw' => 1, 00051 'default' => Linker::link( 00052 $this->mTargetObj->getUserPage(), 00053 htmlspecialchars( $this->mTargetObj->getName() ) 00054 ), 00055 'label-message' => 'emailto', 00056 'id' => 'mw-emailuser-recipient', 00057 ), 00058 'Target' => array( 00059 'type' => 'hidden', 00060 'default' => $this->mTargetObj->getName(), 00061 ), 00062 'Subject' => array( 00063 'type' => 'text', 00064 'default' => wfMsgExt( 'defemailsubject', array( 'content', 'parsemag' ), $this->getUser()->getName() ), 00065 'label-message' => 'emailsubject', 00066 'maxlength' => 200, 00067 'size' => 60, 00068 'required' => 1, 00069 ), 00070 'Text' => array( 00071 'type' => 'textarea', 00072 'rows' => 20, 00073 'cols' => 80, 00074 'label-message' => 'emailmessage', 00075 'required' => 1, 00076 ), 00077 'CCMe' => array( 00078 'type' => 'check', 00079 'label-message' => 'emailccme', 00080 'default' => $this->getUser()->getBoolOption( 'ccmeonemails' ), 00081 ), 00082 ); 00083 } 00084 00085 public function execute( $par ) { 00086 $this->setHeaders(); 00087 $this->outputHeader(); 00088 $out = $this->getOutput(); 00089 $out->addModuleStyles( 'mediawiki.special' ); 00090 $this->mTarget = is_null( $par ) 00091 ? $this->getRequest()->getVal( 'wpTarget', $this->getRequest()->getVal( 'target', '' ) ) 00092 : $par; 00093 // error out if sending user cannot do this 00094 $error = self::getPermissionsError( $this->getUser(), $this->getRequest()->getVal( 'wpEditToken' ) ); 00095 switch ( $error ) { 00096 case null: 00097 # Wahey! 00098 break; 00099 case 'badaccess': 00100 throw new PermissionsError( 'sendemail' ); 00101 case 'blockedemailuser': 00102 throw new UserBlockedError( $this->getUser()->mBlock ); 00103 case 'actionthrottledtext': 00104 throw new ThrottledError; 00105 case 'mailnologin': 00106 case 'usermaildisabled': 00107 throw new ErrorPageError( $error, "{$error}text" ); 00108 default: 00109 # It's a hook error 00110 list( $title, $msg, $params ) = $error; 00111 throw new ErrorPageError( $title, $msg, $params ); 00112 } 00113 // Got a valid target user name? Else ask for one. 00114 $ret = self::getTarget( $this->mTarget ); 00115 if( !$ret instanceof User ) { 00116 if( $this->mTarget != '' ) { 00117 $ret = ( $ret == 'notarget' ) ? 'emailnotarget' : ( $ret . 'text' ); 00118 $out->wrapWikiMsg( "<p class='error'>$1</p>", $ret ); 00119 } 00120 $out->addHTML( $this->userForm( $this->mTarget ) ); 00121 return false; 00122 } 00123 00124 $this->mTargetObj = $ret; 00125 00126 $form = new HTMLForm( $this->getFormFields(), $this->getContext() ); 00127 $form->addPreText( wfMsgExt( 'emailpagetext', 'parseinline' ) ); 00128 $form->setSubmitText( wfMsg( 'emailsend' ) ); 00129 $form->setTitle( $this->getTitle() ); 00130 $form->setSubmitCallback( array( __CLASS__, 'submit' ) ); 00131 $form->setWrapperLegend( wfMsgExt( 'email-legend', 'parsemag' ) ); 00132 $form->loadData(); 00133 00134 if( !wfRunHooks( 'EmailUserForm', array( &$form ) ) ) { 00135 return false; 00136 } 00137 00138 $out->setPageTitle( $this->msg( 'emailpage' ) ); 00139 $result = $form->show(); 00140 00141 if( $result === true || ( $result instanceof Status && $result->isGood() ) ) { 00142 $out->setPageTitle( $this->msg( 'emailsent' ) ); 00143 $out->addWikiMsg( 'emailsenttext' ); 00144 $out->returnToMain( false, $this->mTargetObj->getUserPage() ); 00145 } 00146 } 00147 00154 public static function getTarget( $target ) { 00155 if ( $target == '' ) { 00156 wfDebug( "Target is empty.\n" ); 00157 return 'notarget'; 00158 } 00159 00160 $nu = User::newFromName( $target ); 00161 if( !$nu instanceof User || !$nu->getId() ) { 00162 wfDebug( "Target is invalid user.\n" ); 00163 return 'notarget'; 00164 } elseif ( !$nu->isEmailConfirmed() ) { 00165 wfDebug( "User has no valid email.\n" ); 00166 return 'noemail'; 00167 } elseif ( !$nu->canReceiveEmail() ) { 00168 wfDebug( "User does not allow user emails.\n" ); 00169 return 'nowikiemail'; 00170 } 00171 00172 return $nu; 00173 } 00174 00182 public static function getPermissionsError( $user, $editToken ) { 00183 global $wgEnableEmail, $wgEnableUserEmail; 00184 if( !$wgEnableEmail || !$wgEnableUserEmail ) { 00185 return 'usermaildisabled'; 00186 } 00187 00188 if( !$user->isAllowed( 'sendemail' ) ) { 00189 return 'badaccess'; 00190 } 00191 00192 if( !$user->isEmailConfirmed() ) { 00193 return 'mailnologin'; 00194 } 00195 00196 if( $user->isBlockedFromEmailuser() ) { 00197 wfDebug( "User is blocked from sending e-mail.\n" ); 00198 return "blockedemailuser"; 00199 } 00200 00201 if( $user->pingLimiter( 'emailuser' ) ) { 00202 wfDebug( "Ping limiter triggered.\n" ); 00203 return 'actionthrottledtext'; 00204 } 00205 00206 $hookErr = false; 00207 wfRunHooks( 'UserCanSendEmail', array( &$user, &$hookErr ) ); 00208 wfRunHooks( 'EmailUserPermissionsErrors', array( $user, $editToken, &$hookErr ) ); 00209 if ( $hookErr ) { 00210 return $hookErr; 00211 } 00212 00213 return null; 00214 } 00215 00222 protected function userForm( $name ) { 00223 global $wgScript; 00224 $string = Xml::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript, 'id' => 'askusername' ) ) . 00225 Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) . 00226 Xml::openElement( 'fieldset' ) . 00227 Html::rawElement( 'legend', null, wfMessage( 'emailtarget' )->parse() ) . 00228 Xml::inputLabel( wfMessage( 'emailusername' )->text(), 'target', 'emailusertarget', 30, $name ) . ' ' . 00229 Xml::submitButton( wfMessage( 'emailusernamesubmit' )->text() ) . 00230 Xml::closeElement( 'fieldset' ) . 00231 Xml::closeElement( 'form' ) . "\n"; 00232 return $string; 00233 } 00234 00243 public static function submit( $data ) { 00244 global $wgUser, $wgUserEmailUseReplyTo; 00245 00246 $target = self::getTarget( $data['Target'] ); 00247 if( !$target instanceof User ) { 00248 return wfMsgExt( $target . 'text', 'parse' ); 00249 } 00250 $to = new MailAddress( $target ); 00251 $from = new MailAddress( $wgUser ); 00252 $subject = $data['Subject']; 00253 $text = $data['Text']; 00254 00255 // Add a standard footer and trim up trailing newlines 00256 $text = rtrim( $text ) . "\n\n-- \n"; 00257 $text .= wfMsgExt( 00258 'emailuserfooter', 00259 array( 'content', 'parsemag' ), 00260 array( $from->name, $to->name ) 00261 ); 00262 00263 $error = ''; 00264 if( !wfRunHooks( 'EmailUser', array( &$to, &$from, &$subject, &$text, &$error ) ) ) { 00265 return $error; 00266 } 00267 00268 if( $wgUserEmailUseReplyTo ) { 00269 // Put the generic wiki autogenerated address in the From: 00270 // header and reserve the user for Reply-To. 00271 // 00272 // This is a bit ugly, but will serve to differentiate 00273 // wiki-borne mails from direct mails and protects against 00274 // SPF and bounce problems with some mailers (see below). 00275 global $wgPasswordSender, $wgPasswordSenderName; 00276 $mailFrom = new MailAddress( $wgPasswordSender, $wgPasswordSenderName ); 00277 $replyTo = $from; 00278 } else { 00279 // Put the sending user's e-mail address in the From: header. 00280 // 00281 // This is clean-looking and convenient, but has issues. 00282 // One is that it doesn't as clearly differentiate the wiki mail 00283 // from "directly" sent mails. 00284 // 00285 // Another is that some mailers (like sSMTP) will use the From 00286 // address as the envelope sender as well. For open sites this 00287 // can cause mails to be flunked for SPF violations (since the 00288 // wiki server isn't an authorized sender for various users' 00289 // domains) as well as creating a privacy issue as bounces 00290 // containing the recipient's e-mail address may get sent to 00291 // the sending user. 00292 $mailFrom = $from; 00293 $replyTo = null; 00294 } 00295 00296 $status = UserMailer::send( $to, $mailFrom, $subject, $text, $replyTo ); 00297 00298 if( !$status->isGood() ) { 00299 return $status; 00300 } else { 00301 // if the user requested a copy of this mail, do this now, 00302 // unless they are emailing themselves, in which case one 00303 // copy of the message is sufficient. 00304 if ( $data['CCMe'] && $to != $from ) { 00305 $cc_subject = wfMsg( 00306 'emailccsubject', 00307 $target->getName(), 00308 $subject 00309 ); 00310 wfRunHooks( 'EmailUserCC', array( &$from, &$from, &$cc_subject, &$text ) ); 00311 $ccStatus = UserMailer::send( $from, $from, $cc_subject, $text ); 00312 $status->merge( $ccStatus ); 00313 } 00314 00315 wfRunHooks( 'EmailUserComplete', array( $to, $from, $subject, $text ) ); 00316 return $status; 00317 } 00318 } 00319 }