r64903 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r64902‎ | r64903 | r64904 >
Date:21:14, 10 April 2010
Author:happy-melon
Status:resolved (Comments)
Tags:
Comment:
Overhaul Special:EmailUser, use HTMLForm, a SpecialPage-derived class, and general tidy up. Message change got muddled into r64901.
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/SpecialPage.php (modified) (history)
  • /trunk/phase3/includes/api/ApiEmailUser.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialEmailuser.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiEmailUser.php
@@ -38,10 +38,6 @@
3939
4040 public function execute() {
4141 global $wgUser;
42 - // Check whether email is enabled
43 - if ( !EmailUserForm::userEmailEnabled() ) {
44 - $this->dieUsageMsg( array( 'usermaildisabled' ) );
45 - }
4642
4743 $params = $this->extractRequestParams();
4844 // Check required parameters
@@ -53,25 +49,30 @@
5450 }
5551
5652 // Validate target
57 - $targetUser = EmailUserForm::validateEmailTarget( $params['target'] );
 53+ $targetUser = SpecialEmailuser::getTarget( $params['target'] );
5854 if ( !( $targetUser instanceof User ) ) {
5955 $this->dieUsageMsg( array( $targetUser ) );
6056 }
6157
62 - // Check permissions
63 - $error = EmailUserForm::getPermissionsError( $wgUser, $params['token'] );
 58+ // Check permissions and errors
 59+ $error = SpecialEmailuser::getPermissionsError( $wgUser, $params['token'] );
6460 if ( $error ) {
6561 $this->dieUsageMsg( array( $error ) );
6662 }
6763
68 - $form = new EmailUserForm( $targetUser, $params['text'], $params['subject'], $params['ccme'] );
69 - $retval = $form->doSubmit();
70 - if ( is_null( $retval ) ) {
 64+ $data = array(
 65+ 'Target' => $targetUser->getName(),
 66+ 'Text' => $params['text'],
 67+ 'Subject' => $params['subject'],
 68+ 'CCMe' => $params['ccme'],
 69+ );
 70+ $retval = SpecialEmailuser::submit( $data );
 71+ if ( $retval === true ) {
7172 $result = array( 'result' => 'Success' );
7273 } else {
7374 $result = array(
7475 'result' => 'Failure',
75 - 'message' => $retval->getMessage()
 76+ 'message' => $retval
7677 );
7778 }
7879
Index: trunk/phase3/includes/AutoLoader.php
@@ -512,7 +512,7 @@
513513 'DoubleRedirectsPage' => 'includes/specials/SpecialDoubleRedirects.php',
514514 'EmailConfirmation' => 'includes/specials/SpecialConfirmemail.php',
515515 'EmailInvalidation' => 'includes/specials/SpecialConfirmemail.php',
516 - 'EmailUserForm' => 'includes/specials/SpecialEmailuser.php',
 516+ 'SpecialEmailUser' => 'includes/specials/SpecialEmailuser.php',
517517 'FakeResultWrapper' => 'includes/specials/SpecialAllmessages.php',
518518 'FewestrevisionsPage' => 'includes/specials/SpecialFewestrevisions.php',
519519 'FileDuplicateSearchPage' => 'includes/specials/SpecialFileDuplicateSearch.php',
Index: trunk/phase3/includes/specials/SpecialEmailuser.php
@@ -4,335 +4,177 @@
55 * @ingroup SpecialPage
66 */
77
8 -/**
9 - * Constructor for Special:Emailuser.
10 - */
11 -function wfSpecialEmailuser( $par ) {
12 - global $wgRequest, $wgUser, $wgOut;
13 -
14 - if ( !EmailUserForm::userEmailEnabled() ) {
15 - $wgOut->showErrorPage( 'nosuchspecialpage', 'nospecialpagetext' );
16 - return;
 8+class SpecialEmailUser extends UnlistedSpecialPage {
 9+ protected $mTarget;
 10+
 11+ public function __construct(){
 12+ parent::__construct( 'Emailuser' );
1713 }
18 -
19 - $action = $wgRequest->getVal( 'action' );
20 - $target = isset($par) ? $par : $wgRequest->getVal( 'target' );
21 - $targetUser = EmailUserForm::validateEmailTarget( $target );
22 -
23 - if ( !( $targetUser instanceof User ) ) {
24 - $wgOut->showErrorPage( $targetUser.'title', $targetUser.'text' );
25 - return;
 14+
 15+ protected function getFormFields(){
 16+ global $wgUser;
 17+ return array(
 18+ 'From' => array(
 19+ 'type' => 'info',
 20+ 'raw' => 1,
 21+ 'default' => $wgUser->getSkin()->link(
 22+ $wgUser->getUserPage(),
 23+ htmlspecialchars( $wgUser->getName() )
 24+ ),
 25+ 'label-message' => 'emailfrom',
 26+ 'id' => 'mw-emailuser-sender',
 27+ ),
 28+ 'To' => array(
 29+ 'type' => 'info',
 30+ 'raw' => 1,
 31+ 'default' => $wgUser->getSkin()->link(
 32+ $this->mTargetObj->getUserPage(),
 33+ htmlspecialchars( $this->mTargetObj->getName() )
 34+ ),
 35+ 'label-message' => 'emailto',
 36+ 'id' => 'mw-emailuser-recipient',
 37+ ),
 38+ 'Target' => array(
 39+ 'type' => 'hidden',
 40+ 'default' => $this->mTargetObj->getName(),
 41+ ),
 42+ 'Subject' => array(
 43+ 'type' => 'text',
 44+ 'default' => wfMsgExt( 'defemailsubject', array( 'content', 'parsemag' ) ),
 45+ 'label-message' => 'emailsubject',
 46+ 'maxlength' => 200,
 47+ 'size' => 60,
 48+ 'required' => 1,
 49+ ),
 50+ 'Text' => array(
 51+ 'type' => 'textarea',
 52+ 'rows' => 20,
 53+ 'cols' => 80,
 54+ 'label-message' => 'emailmessage',
 55+ 'required' => 1,
 56+ ),
 57+ 'CCMe' => array(
 58+ 'type' => 'check',
 59+ 'label-message' => 'emailccme',
 60+ 'default' => $wgUser->getBoolOption( 'ccmeonemails' ),
 61+ ),
 62+ );
2663 }
27 -
28 - $form = new EmailUserForm( $targetUser,
29 - $wgRequest->getText( 'wpText' ),
30 - $wgRequest->getText( 'wpSubject' ),
31 - $wgRequest->getBool( 'wpCCMe' ) );
32 - if ( $action == 'success' ) {
33 - $form->showSuccess();
34 - return;
35 - }
36 -
37 - $error = EmailUserForm::getPermissionsError( $wgUser, $wgRequest->getVal( 'wpEditToken' ) );
38 - if ( $error ) {
 64+
 65+ public function execute( $par=null ) {
 66+ global $wgRequest, $wgOut, $wgUser;
 67+ $this->mTarget = is_null( $par )
 68+ ? $wgRequest->getVal( 'wpTarget', '' )
 69+ : $par;
 70+
 71+ $ret = self::getTarget( $this->mTarget );
 72+ if( $ret instanceof User ){
 73+ $this->mTargetObj = $ret;
 74+ } else {
 75+ $wgOut->showErrorPage( "{$ret}title", "{$ret}text" );
 76+ return false;
 77+ }
 78+
 79+ $error = self::getPermissionsError( $wgUser, $wgRequest->getVal( 'wpEditToken' ) );
3980 switch ( $error ) {
 81+ case null:
 82+ # Wahey!
 83+ break;
 84+ case 'badaccess':
 85+ $wgOut->permissionRequired( 'sendemail' );
 86+ return;
4087 case 'blockedemailuser':
4188 $wgOut->blockedPage();
4289 return;
4390 case 'actionthrottledtext':
4491 $wgOut->rateLimited();
4592 return;
46 - case 'sessionfailure':
47 - $form->showForm();
48 - return;
4993 case 'mailnologin':
50 - $wgOut->showErrorPage( 'mailnologin', 'mailnologintext' );
 94+ case 'usermaildisabled':
 95+ $wgOut->showErrorPage( $error, "{$error}text" );
5196 return;
5297 default:
53 - // It's a hook error
 98+ # It's a hook error
5499 list( $title, $msg, $params ) = $error;
55100 $wgOut->showErrorPage( $title, $msg, $params );
56101 return;
57 -
58102 }
59 - }
60 -
61 - if ( "submit" == $action && $wgRequest->wasPosted() ) {
62 - $result = $form->doSubmit();
63 -
64 - if ( !is_null( $result ) ) {
65 - $wgOut->addHTML( wfMsg( "usermailererror" ) .
66 - ' ' . htmlspecialchars( $result->getMessage() ) );
67 - } else {
68 - $titleObj = SpecialPage::getTitleFor( "Emailuser" );
69 - $encTarget = wfUrlencode( $form->getTarget()->getName() );
70 - $wgOut->redirect( $titleObj->getFullURL( "target={$encTarget}&action=success" ) );
 103+
 104+ $form = new HTMLForm( $this->getFormFields() );
 105+ $form->addPreText( wfMsgExt( 'emailpagetext', 'parseinline' ) );
 106+ $form->setSubmitText( wfMsg( 'emailsend' ) );
 107+ $form->setTitle( $this->getTitle() );
 108+ $form->setSubmitCallback( array( __CLASS__, 'submit' ) );
 109+ $form->setWrapperLegend( wfMsgExt( 'email-legend', 'parsemag' ) );
 110+ $form->loadData();
 111+
 112+ if( !wfRunHooks( 'EmailUserForm', array( &$form ) ) ){
 113+ return false;
71114 }
72 - } else {
73 - $form->showForm();
74 - }
75 -}
76 -
77 -/**
78 - * Implements the Special:Emailuser web interface, and invokes
79 - * UserMailer::send() for sending the email message.
80 - *
81 - * @ingroup SpecialPage
82 - */
83 -class EmailUserForm {
84 -
85 - var $target;
86 - var $text, $subject;
87 - var $cc_me; // Whether user requested to be sent a separate copy of their email.
88 -
89 - /**
90 - * Constructor
91 - *
92 - * @param $target User object
93 - * @param $text String: message contents
94 - * @param $subject String: message subject
95 - * @param $cc_me Boolean: wheter to send a copy of the message to the sender user
96 - */
97 - public function EmailUserForm( $target, $text, $subject, $cc_me ) {
98 - $this->target = $target;
99 - $this->text = $text;
100 - $this->subject = $subject;
101 - $this->cc_me = $cc_me;
102 - }
103 -
104 - /**
105 - * Display the form to send a email
106 - */
107 - public function showForm() {
108 - global $wgOut, $wgUser;
109 - $skin = $wgUser->getSkin();
110 -
111 - $wgOut->setPagetitle( wfMsg( "emailpage" ) );
112 - $wgOut->addWikiMsg( "emailpagetext" );
113 -
114 - if ( $this->subject === "" ) {
115 - $this->subject = wfMsgExt( 'defemailsubject', array( 'content', 'parsemag' ) );
 115+
 116+ $wgOut->setPagetitle( wfMsg( 'emailpage' ) );
 117+ $result = $form->show();
 118+
 119+ if( $result === true ){
 120+ $wgOut->setPagetitle( wfMsg( 'emailsent' ) );
 121+ $wgOut->addWikiMsg( 'emailsenttext' );
 122+ $wgOut->returnToMain( false, $this->mTargetObj->getUserPage() );
116123 }
117 -
118 - $titleObj = SpecialPage::getTitleFor( "Emailuser" );
119 - $action = $titleObj->getLocalURL( "target=" .
120 - urlencode( $this->target->getName() ) . "&action=submit" );
121 -
122 - $wgOut->addHTML(
123 - Xml::openElement( 'form', array( 'method' => 'post', 'action' => $action, 'id' => 'emailuser' ) ) .
124 - Xml::openElement( 'fieldset' ) .
125 - Xml::element( 'legend', null, wfMsgExt( 'email-legend', 'parsemag' ) ) .
126 - Xml::openElement( 'table', array( 'class' => 'mw-emailuser-table' ) ) .
127 - "<tr>
128 - <td class='mw-label'>" .
129 - Xml::label( wfMsg( 'emailfrom' ), 'emailfrom' ) .
130 - "</td>
131 - <td class='mw-input' id='mw-emailuser-sender'>" .
132 - $skin->link( $wgUser->getUserPage(), htmlspecialchars( $wgUser->getName() ) ) .
133 - "</td>
134 - </tr>
135 - <tr>
136 - <td class='mw-label'>" .
137 - Xml::label( wfMsg( 'emailto' ), 'emailto' ) .
138 - "</td>
139 - <td class='mw-input' id='mw-emailuser-recipient'>" .
140 - $skin->link( $this->target->getUserPage(), htmlspecialchars( $this->target->getName() ) ) .
141 - "</td>
142 - </tr>
143 - <tr>
144 - <td class='mw-label'>" .
145 - Xml::label( wfMsg( 'emailsubject' ), 'wpSubject' ) .
146 - "</td>
147 - <td class='mw-input'>" .
148 - Xml::input( 'wpSubject', 60, $this->subject, array( 'type' => 'text', 'maxlength' => 200 ) ) .
149 - "</td>
150 - </tr>
151 - <tr>
152 - <td class='mw-label'>" .
153 - Xml::label( wfMsg( 'emailmessage' ), 'wpText' ) .
154 - "</td>
155 - <td class='mw-input'>" .
156 - Xml::textarea( 'wpText', $this->text, 80, 20, array( 'id' => 'wpText' ) ) .
157 - "</td>
158 - </tr>
159 - <tr>
160 - <td></td>
161 - <td class='mw-input'>" .
162 - Xml::checkLabel( wfMsg( 'emailccme' ), 'wpCCMe', 'wpCCMe', $wgUser->getBoolOption( 'ccmeonemails' ) ) .
163 - "</td>
164 - </tr>
165 - <tr>
166 - <td></td>
167 - <td class='mw-submit'>" .
168 - Xml::submitButton( wfMsg( 'emailsend' ), array( 'name' => 'wpSend', 'accesskey' => 's' ) ) .
169 - "</td>
170 - </tr>" .
171 - Xml::hidden( 'wpEditToken', $wgUser->editToken() ) .
172 - Xml::closeElement( 'table' ) .
173 - Xml::closeElement( 'fieldset' ) .
174 - Xml::closeElement( 'form' )
175 - );
176124 }
177125
178126 /**
179 - * Really send a mail. Permissions should have been checked using
180 - * EmailUserForm::getPermissionsError. It is probably also a good idea to
181 - * check the edit token and ping limiter in advance.
182 - *
183 - * @return Mixed: WikiError on error or null
184 - */
185 - public function doSubmit() {
186 - global $wgUser, $wgUserEmailUseReplyTo, $wgSiteName;
187 -
188 - $to = new MailAddress( $this->target );
189 - $from = new MailAddress( $wgUser );
190 - $subject = $this->subject;
191 -
192 - // Add a standard footer and trim up trailing newlines
193 - $this->text = rtrim($this->text) . "\n\n-- \n" . wfMsgExt( 'emailuserfooter',
194 - array( 'content', 'parsemag' ), array( $from->name, $to->name ) );
195 -
196 - if( wfRunHooks( 'EmailUser', array( &$to, &$from, &$subject, &$this->text ) ) ) {
197 -
198 - if( $wgUserEmailUseReplyTo ) {
199 - // Put the generic wiki autogenerated address in the From:
200 - // header and reserve the user for Reply-To.
201 - //
202 - // This is a bit ugly, but will serve to differentiate
203 - // wiki-borne mails from direct mails and protects against
204 - // SPF and bounce problems with some mailers (see below).
205 - global $wgPasswordSender;
206 - $mailFrom = new MailAddress( $wgPasswordSender );
207 - $replyTo = $from;
208 - } else {
209 - // Put the sending user's e-mail address in the From: header.
210 - //
211 - // This is clean-looking and convenient, but has issues.
212 - // One is that it doesn't as clearly differentiate the wiki mail
213 - // from "directly" sent mails.
214 - //
215 - // Another is that some mailers (like sSMTP) will use the From
216 - // address as the envelope sender as well. For open sites this
217 - // can cause mails to be flunked for SPF violations (since the
218 - // wiki server isn't an authorized sender for various users'
219 - // domains) as well as creating a privacy issue as bounces
220 - // containing the recipient's e-mail address may get sent to
221 - // the sending user.
222 - $mailFrom = $from;
223 - $replyTo = null;
224 - }
225 -
226 - $mailResult = UserMailer::send( $to, $mailFrom, $subject, $this->text, $replyTo );
227 -
228 - if( WikiError::isError( $mailResult ) ) {
229 - return $mailResult;
230 - } else {
231 - // if the user requested a copy of this mail, do this now,
232 - // unless they are emailing themselves, in which case one copy of the message is sufficient.
233 - if ($this->cc_me && $to != $from) {
234 - $cc_subject = wfMsg('emailccsubject', $this->target->getName(), $subject);
235 - if( wfRunHooks( 'EmailUser', array( &$from, &$from, &$cc_subject, &$this->text ) ) ) {
236 - $ccResult = UserMailer::send( $from, $from, $cc_subject, $this->text );
237 - if( WikiError::isError( $ccResult ) ) {
238 - // At this stage, the user's CC mail has failed, but their
239 - // original mail has succeeded. It's unlikely, but still, what to do?
240 - // We can either show them an error, or we can say everything was fine,
241 - // or we can say we sort of failed AND sort of succeeded. Of these options,
242 - // simply saying there was an error is probably best.
243 - return $ccResult;
244 - }
245 - }
246 - }
247 -
248 - wfRunHooks( 'EmailUserComplete', array( $to, $from, $subject, $this->text ) );
249 - return;
250 - }
251 - }
252 - }
253 -
254 - /**
255 - * Show "Your e-mail message has been sent." message
256 - */
257 - public function showSuccess( &$user = null ) {
258 - global $wgOut;
259 -
260 - if ( is_null($user) )
261 - $user = $this->target;
262 -
263 - $wgOut->setPagetitle( wfMsg( "emailsent" ) );
264 - $wgOut->addWikiMsg( 'emailsenttext' );
265 -
266 - $wgOut->returnToMain( false, $user->getUserPage() );
267 - }
268 -
269 - /**
270 - * Get target user
271 - *
272 - * @return User object
273 - */
274 - public function getTarget() {
275 - return $this->target;
276 - }
277 -
278 - /**
279 - * Check whether user-to-user emails are enabled
280 - *
281 - * @return Boolean
282 - */
283 - public static function userEmailEnabled() {
284 - global $wgEnableEmail, $wgEnableUserEmail;
285 - return $wgEnableEmail && $wgEnableUserEmail;
286 - }
287 -
288 - /**
289127 * Validate target User
290128 *
291129 * @param $target String: target user name
292130 * @return User object on success or a string on error
293131 */
294 - public static function validateEmailTarget( $target ) {
295 - if ( $target == "" ) {
 132+ public static function getTarget( $target ) {
 133+ if ( $target == '' ) {
296134 wfDebug( "Target is empty.\n" );
297 - return "notarget";
 135+ return 'notarget';
298136 }
299137
300138 $nt = Title::newFromURL( $target );
301 - if ( is_null( $nt ) ) {
 139+ if ( !$nt instanceof Title ) {
302140 wfDebug( "Target is invalid title.\n" );
303 - return "notarget";
 141+ return 'notarget';
304142 }
305143
306144 $nu = User::newFromName( $nt->getText() );
307145 if( !$nu instanceof User || !$nu->getId() ) {
308146 wfDebug( "Target is invalid user.\n" );
309 - return "notarget";
 147+ return 'notarget';
310148 } else if ( !$nu->isEmailConfirmed() ) {
311149 wfDebug( "User has no valid email.\n" );
312 - return "noemail";
 150+ return 'noemail';
313151 } else if ( !$nu->canReceiveEmail() ) {
314152 wfDebug( "User does not allow user emails.\n" );
315 - return "nowikiemail";
 153+ return 'nowikiemail';
316154 }
317155
318156 return $nu;
319157 }
320158
321159 /**
322 - * Check whether user is allowed to send email
 160+ * Check whether a user is allowed to send email
323161 *
324162 * @param $user User object
325163 * @param $editToken String: edit token
326164 * @return null on success or string on error
327165 */
328166 public static function getPermissionsError( $user, $editToken ) {
329 - if( !$user->canSendEmail() ) {
330 - wfDebug( "User can't send.\n" );
331 - // FIXME: this is also the error if user is in a group
332 - // that is not allowed to send e-mail (no right
333 - // 'sendemail'). Error messages should probably
334 - // be more fine grained.
335 - return "mailnologin";
 167+ global $wgEnableEmail, $wgEnableUserEmail;
 168+ if( !$wgEnableEmail || !$wgEnableUserEmail ){
 169+ return 'usermaildisabled';
336170 }
 171+
 172+ if( !$user->isAllowed( 'sendemail' ) ) {
 173+ return 'badaccess';
 174+ }
 175+
 176+ if( !$user->isEmailConfirmed() ){
 177+ return 'mailnologin';
 178+ }
337179
338180 if( $user->isBlockedFromEmailuser() ) {
339181 wfDebug( "User is blocked from sending e-mail.\n" );
@@ -344,31 +186,105 @@
345187 return 'actionthrottledtext';
346188 }
347189
348 - $hookErr = null;
 190+ $hookErr = false;
 191+ wfRunHooks( 'UserCanSendEmail', array( &$user, &$hookErr ) );
349192 wfRunHooks( 'EmailUserPermissionsErrors', array( $user, $editToken, &$hookErr ) );
350 -
351 - if ($hookErr) {
 193+ if ( $hookErr ) {
352194 return $hookErr;
353195 }
354 -
355 - if( !$user->matchEditToken( $editToken ) ) {
356 - wfDebug( "Matching edit token failed.\n" );
357 - return 'sessionfailure';
358 - }
 196+
 197+ return null;
359198 }
360199
361200 /**
362 - * Get a EmailUserForm object
 201+ * Really send a mail. Permissions should have been checked using
 202+ * getPermissionsError(). It is probably also a good
 203+ * idea to check the edit token and ping limiter in advance.
363204 *
364 - * @param $target String: user name
365 - * @param $text String: message contents
366 - * @param $subject String: message subject
367 - * @param $cc_me Boolean: wheter to send a copy of the message to the sender user
368 - * @return EmailUserForm object
 205+ * @return Mixed: True on success, String on error
369206 */
370 - public static function newFromURL( $target, $text, $subject, $cc_me ) {
371 - $nt = Title::newFromURL( $target );
372 - $nu = User::newFromName( $nt->getText() );
373 - return new EmailUserForm( $nu, $text, $subject, $cc_me );
 207+ public static function submit( $data ) {
 208+ global $wgUser, $wgUserEmailUseReplyTo, $wgSiteName;
 209+
 210+ $target = self::getTarget( $data['Target'] );
 211+ if( !$target instanceof User ){
 212+ return wfMsgExt( $to, 'parse' );
 213+ }
 214+ $to = new MailAddress( $target );
 215+ $from = new MailAddress( $wgUser );
 216+ $subject = $data['Subject'];
 217+ $text = $data['Text'];
 218+
 219+ // Add a standard footer and trim up trailing newlines
 220+ $text = rtrim( $text ) . "\n\n-- \n";
 221+ $text .= wfMsgExt(
 222+ 'emailuserfooter',
 223+ array( 'content', 'parsemag' ),
 224+ array( $from->name, $to->name )
 225+ );
 226+
 227+ $error = '';
 228+ if( !wfRunHooks( 'EmailUser', array( &$to, &$from, &$subject, &$text, &$error ) ) ) {
 229+ return $error;
 230+ }
 231+
 232+ if( $wgUserEmailUseReplyTo ) {
 233+ // Put the generic wiki autogenerated address in the From:
 234+ // header and reserve the user for Reply-To.
 235+ //
 236+ // This is a bit ugly, but will serve to differentiate
 237+ // wiki-borne mails from direct mails and protects against
 238+ // SPF and bounce problems with some mailers (see below).
 239+ global $wgPasswordSender;
 240+ $mailFrom = new MailAddress( $wgPasswordSender );
 241+ $replyTo = $from;
 242+ } else {
 243+ // Put the sending user's e-mail address in the From: header.
 244+ //
 245+ // This is clean-looking and convenient, but has issues.
 246+ // One is that it doesn't as clearly differentiate the wiki mail
 247+ // from "directly" sent mails.
 248+ //
 249+ // Another is that some mailers (like sSMTP) will use the From
 250+ // address as the envelope sender as well. For open sites this
 251+ // can cause mails to be flunked for SPF violations (since the
 252+ // wiki server isn't an authorized sender for various users'
 253+ // domains) as well as creating a privacy issue as bounces
 254+ // containing the recipient's e-mail address may get sent to
 255+ // the sending user.
 256+ $mailFrom = $from;
 257+ $replyTo = null;
 258+ }
 259+
 260+ $mailResult = UserMailer::send( $to, $mailFrom, $subject, $text, $replyTo );
 261+
 262+ if( WikiError::isError( $mailResult ) && false ) {
 263+ return $mailResult->getMessage();
 264+ } else {
 265+ // if the user requested a copy of this mail, do this now,
 266+ // unless they are emailing themselves, in which case one
 267+ // copy of the message is sufficient.
 268+ if ( $data['CCMe'] && $to != $from ) {
 269+ $cc_subject = wfMsg(
 270+ 'emailccsubject',
 271+ $target->getName(),
 272+ $subject
 273+ );
 274+ wfRunHooks( 'EmailUserCC', array( &$from, &$from, &$cc_subject, &$text ) );
 275+ $ccResult = UserMailer::send( $from, $from, $cc_subject, $text );
 276+ if( WikiError::isError( $ccResult ) ) {
 277+ // At this stage, the user's CC mail has failed, but their
 278+ // original mail has succeeded. It's unlikely, but still,
 279+ // what to do? We can either show them an error, or we can
 280+ // say everything was fine, or we can say we sort of failed
 281+ // AND sort of succeeded. Of these options, simply saying
 282+ // there was an error is probably best.
 283+ return $ccResult->getMessage();
 284+ }
 285+ }
 286+
 287+ wfRunHooks( 'EmailUserComplete', array( $to, $from, $subject, $text ) );
 288+ return true;
 289+ }
374290 }
375291 }
Index: trunk/phase3/includes/SpecialPage.php
@@ -181,7 +181,7 @@
182182 # Unlisted / redirects
183183 'Blankpage' => 'SpecialBlankpage',
184184 'Blockme' => array( 'UnlistedSpecialPage', 'Blockme' ),
185 - 'Emailuser' => array( 'UnlistedSpecialPage', 'Emailuser' ),
 185+ 'Emailuser' => 'SpecialEmailUser',
186186 'Listadmins' => array( 'SpecialRedirectToSpecial', 'Listadmins', 'Listusers', 'sysop' ),
187187 'Listbots' => array( 'SpecialRedirectToSpecial', 'Listbots', 'Listusers', 'bot' ),
188188 'Movepage' => array( 'UnlistedSpecialPage', 'Movepage' ),

Follow-up revisions

RevisionCommit summaryAuthorDate
r64907Add messages.inc entry for r64903.happy-melon21:23, 10 April 2010
r64925Fixes for r64903:...ialex07:57, 11 April 2010
r64997Documented hooks added in r64903ialex17:33, 13 April 2010
r67277Follow-up to r64903; fix field names broken by r65040.happy-melon09:43, 3 June 2010
r78251Follow-up r64903: rm leftover debugging code.happy-melon15:40, 12 December 2010

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r64901Follow-up to r64866 - add message, and apply the same validation to TextareaF...happy-melon21:10, 10 April 2010

Comments

#Comment by Raymond (talk | contribs)   06:16, 11 April 2010

Seen at translatewiki;

PHP Strict Standards: Declaration of SpecialEmailUser::execute() should be compatible with that of SpecialPage::execute() in /www/w/includes/AutoLoader.php on line 657
#Comment by Nikerabbit (talk | contribs)   07:37, 11 April 2010
+		if( !$target instanceof User ){
+			return wfMsgExt( $to, 'parse' );
+		}
+		$to = new MailAddress( $target );

Ahem...

#Comment by IAlex (talk | contribs)   07:58, 11 April 2010

Both done in r64925.

#Comment by OverlordQ (talk | contribs)   02:20, 3 June 2010

Breaks functionality completely.

You rename the form fields, but dont change them in the rest of the script.

#Comment by Happy-melon (talk | contribs)   09:17, 3 June 2010

This is a throwover from r65040, I believe.

#Comment by Happy-melon (talk | contribs)   09:43, 3 June 2010

Fixed in r67277.

#Comment by Catrope (talk | contribs)   12:53, 5 December 2010
+		if( WikiError::isError( $mailResult ) && false ) {

That looks like debugging code (the && false part)?

#Comment by Happy-melon (talk | contribs)   15:41, 12 December 2010

Yes, fixed in r78351.

#Comment by Catrope (talk | contribs)   15:45, 12 December 2010
#Comment by Catrope (talk | contribs)   15:46, 12 December 2010

Untagging 1.17: this was committed 8 months before 1.17 was branched

#Comment by Catrope (talk | contribs)   16:42, 14 December 2010

API part looks good, haven't reviewed the special page part.

Status & tagging log