Revert r34906, r34907, r34928 -- mixing high-level data into low-level storage functi...
[lhc/web/wiklou.git] / includes / SpecialEmailuser.php
1 <?php
2 /**
3 *
4 * @addtogroup SpecialPage
5 */
6
7 /**
8 * @todo document
9 */
10 function wfSpecialEmailuser( $par ) {
11 global $wgRequest, $wgUser, $wgOut;
12
13 $target = isset($par) ? $par : $wgRequest->getVal( 'target' );
14 $error = EmailUserForm::getPermissionsError( $target );
15 if ( $error ) {
16 if ( $error[0] === "blockedemailuser" ) {
17 $wgOut->blockedPage();
18 return;
19 } else {
20 $wgOut->showErrorPage( $error[0], $error[1] );
21 return;
22 }
23 }
24
25 $form = EmailUserForm::newFromURL( $target,
26 $wgRequest->getText( 'wpText' ),
27 $wgRequest->getText( 'wpSubject' ),
28 $wgRequest->getBool( 'wpCCMe' ) );
29
30 $action = $wgRequest->getVal( 'action' );
31 if ( "success" == $action ) {
32 $form->showSuccess();
33 } else if ( "submit" == $action && $wgRequest->wasPosted() &&
34 $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) )
35 {
36 # Check against the rate limiter
37 if( $wgUser->pingLimiter( 'emailuser' ) ) {
38 $wgOut->rateLimited();
39 return;
40 }
41
42 $result = $form->doSubmit();
43
44 if ( !is_null( $result ) ) {
45 $wgOut->addHTML( wfMsg( "usermailererror" ) .
46 ' ' . htmlspecialchars( $result->getMessage() ) );
47 } else {
48 $titleObj = SpecialPage::getTitleFor( "Emailuser" );
49 $encTarget = wfUrlencode( $form->getTarget()->getName() );
50 $wgOut->redirect( $titleObj->getFullURL( "target={$encTarget}&action=success" ) );
51 }
52 } else {
53 $form->showForm();
54 }
55 }
56
57 /**
58 * Implements the Special:Emailuser web interface, and invokes userMailer for sending the email message.
59 * @addtogroup SpecialPage
60 */
61 class EmailUserForm {
62
63 var $target;
64 var $text, $subject;
65 var $cc_me; // Whether user requested to be sent a separate copy of their email.
66
67 /**
68 * @param User $target
69 */
70 function EmailUserForm( $target, $text, $subject, $cc_me ) {
71 $this->target = $target;
72 $this->text = $text;
73 $this->subject = $subject;
74 $this->cc_me = $cc_me;
75 }
76
77 function showForm() {
78 global $wgOut, $wgUser;
79 $skin = $wgUser->getSkin();
80
81 $wgOut->setPagetitle( wfMsg( "emailpage" ) );
82 $wgOut->addWikiMsg( "emailpagetext" );
83
84 if ( $this->subject === "" ) {
85 $this->subject = wfMsgForContent( "defemailsubject" );
86 }
87
88 $emf = wfMsg( "emailfrom" );
89 $senderLink = $skin->makeLinkObj(
90 $wgUser->getUserPage(), htmlspecialchars( $wgUser->getName() ) );
91 $emt = wfMsg( "emailto" );
92 $recipientLink = $skin->makeLinkObj(
93 $this->target->getUserPage(), htmlspecialchars( $this->target->getName() ) );
94 $emr = wfMsg( "emailsubject" );
95 $emm = wfMsg( "emailmessage" );
96 $ems = wfMsg( "emailsend" );
97 $emc = wfMsg( "emailccme" );
98 $encSubject = htmlspecialchars( $this->subject );
99
100 $titleObj = SpecialPage::getTitleFor( "Emailuser" );
101 $action = $titleObj->escapeLocalURL( "target=" .
102 urlencode( $this->target->getName() ) . "&action=submit" );
103 $token = htmlspecialchars( $wgUser->editToken() );
104
105 $wgOut->addHTML( "
106 <form id=\"emailuser\" method=\"post\" action=\"{$action}\">
107 <table border='0' id='mailheader'><tr>
108 <td align='right'>{$emf}:</td>
109 <td align='left'><strong>{$senderLink}</strong></td>
110 </tr><tr>
111 <td align='right'>{$emt}:</td>
112 <td align='left'><strong>{$recipientLink}</strong></td>
113 </tr><tr>
114 <td align='right'>{$emr}:</td>
115 <td align='left'>
116 <input type='text' size='60' maxlength='200' name=\"wpSubject\" value=\"{$encSubject}\" />
117 </td>
118 </tr>
119 </table>
120 <span id='wpTextLabel'><label for=\"wpText\">{$emm}:</label><br /></span>
121 <textarea id=\"wpText\" name=\"wpText\" rows='20' cols='80' style=\"width: 100%;\">" . htmlspecialchars( $this->text ) .
122 "</textarea>
123 " . wfCheckLabel( $emc, 'wpCCMe', 'wpCCMe', $wgUser->getBoolOption( 'ccmeonemails' ) ) . "<br />
124 <input type='submit' name=\"wpSend\" value=\"{$ems}\" />
125 <input type='hidden' name='wpEditToken' value=\"$token\" />
126 </form>\n" );
127
128 }
129
130 /*
131 * Really send a mail. Permissions should have been checked using
132 * EmailUserForm::getPermissionsError. It is probably also a good idea to
133 * check the edit token and ping limiter in advance.
134 */
135 function doSubmit() {
136 global $wgUser, $wgUserEmailUseReplyTo;
137
138 $to = new MailAddress( $this->target );
139 $from = new MailAddress( $wgUser );
140 $subject = $this->subject;
141
142 if( wfRunHooks( 'EmailUser', array( &$to, &$from, &$subject, &$this->text ) ) ) {
143
144 if( $wgUserEmailUseReplyTo ) {
145 // Put the generic wiki autogenerated address in the From:
146 // header and reserve the user for Reply-To.
147 //
148 // This is a bit ugly, but will serve to differentiate
149 // wiki-borne mails from direct mails and protects against
150 // SPF and bounce problems with some mailers (see below).
151 global $wgPasswordSender;
152 $mailFrom = new MailAddress( $wgPasswordSender );
153 $replyTo = $from;
154 } else {
155 // Put the sending user's e-mail address in the From: header.
156 //
157 // This is clean-looking and convenient, but has issues.
158 // One is that it doesn't as clearly differentiate the wiki mail
159 // from "directly" sent mails.
160 //
161 // Another is that some mailers (like sSMTP) will use the From
162 // address as the envelope sender as well. For open sites this
163 // can cause mails to be flunked for SPF violations (since the
164 // wiki server isn't an authorized sender for various users'
165 // domains) as well as creating a privacy issue as bounces
166 // containing the recipient's e-mail address may get sent to
167 // the sending user.
168 $mailFrom = $from;
169 $replyTo = null;
170 }
171
172 $mailResult = UserMailer::send( $to, $mailFrom, $subject, $this->text, $replyTo );
173
174 if( WikiError::isError( $mailResult ) ) {
175 return $mailResult;
176
177 } else {
178
179 // if the user requested a copy of this mail, do this now,
180 // unless they are emailing themselves, in which case one copy of the message is sufficient.
181 if ($this->cc_me && $to != $from) {
182 $cc_subject = wfMsg('emailccsubject', $this->target->getName(), $subject);
183 if( wfRunHooks( 'EmailUser', array( &$from, &$from, &$cc_subject, &$this->text ) ) ) {
184 $ccResult = UserMailer::send( $from, $from, $cc_subject, $this->text );
185 if( WikiError::isError( $ccResult ) ) {
186 // At this stage, the user's CC mail has failed, but their
187 // original mail has succeeded. It's unlikely, but still, what to do?
188 // We can either show them an error, or we can say everything was fine,
189 // or we can say we sort of failed AND sort of succeeded. Of these options,
190 // simply saying there was an error is probably best.
191 return $ccResult->getMessage();
192 }
193 }
194 }
195
196 wfRunHooks( 'EmailUserComplete', array( $to, $from, $subject, $this->text ) );
197 return;
198 }
199 }
200 }
201
202 function showSuccess( &$user = null ) {
203 global $wgOut;
204
205 if ( is_null($user) )
206 $user = $this->target;
207
208 $wgOut->setPagetitle( wfMsg( "emailsent" ) );
209 $wgOut->addHTML( wfMsg( "emailsenttext" ) );
210
211 $wgOut->returnToMain( false, $user->getUserPage() );
212 }
213
214 function getTarget() {
215 return $this->target;
216 }
217
218 static function getPermissionsError ( $target ) {
219 global $wgUser, $wgRequest, $wgEnableEmail, $wgEnableUserEmail;
220
221 if( !( $wgEnableEmail && $wgEnableUserEmail ) )
222 return array( "nosuchspecialpage", "nospecialpagetext" );
223
224 if( !$wgUser->canSendEmail() ) {
225 wfDebug( "User can't send.\n" );
226 return array( "mailnologin", "mailnologintext" );
227 }
228
229 if( $wgUser->isBlockedFromEmailuser() ) {
230 wfDebug( "User is blocked from sending e-mail.\n" );
231 return array( "blockedemailuser", "" );
232 }
233
234 if ( "" == $target ) {
235 wfDebug( "Target is empty.\n" );
236 return array( "notargettitle", "notargettext" );
237 }
238
239 $nt = Title::newFromURL( $target );
240 if ( is_null( $nt ) ) {
241 wfDebug( "Target is invalid title.\n" );
242 return array( "notargettitle", "notargettext" );
243 }
244
245 $nu = User::newFromName( $nt->getText() );
246 if( is_null( $nu ) || !$nu->canReceiveEmail() ) {
247 wfDebug( "Target is invalid user or can't receive.\n" );
248 return array( "noemailtitle", "noemailtext" );
249 }
250
251 return;
252 }
253
254 static function newFromURL( $target, $text, $subject, $cc_me )
255 {
256 $nt = Title::newFromURL( $target );
257 $nu = User::newFromName( $nt->getText() );
258 return new EmailUserForm( $nu, $text, $subject, $cc_me );
259 }
260 }