40 parent::__construct(
'Emailuser' );
49 if ( !$target instanceof
User ) {
50 return $this->
msg(
'emailuser-title-notarget' )->text();
53 return $this->
msg(
'emailuser-title-target', $target->getName() )->text();
63 $this->
getUser()->getUserPage(),
66 'label-message' =>
'emailfrom',
67 'id' =>
'mw-emailuser-sender',
73 $this->mTargetObj->getUserPage(),
74 $this->mTargetObj->getName()
76 'label-message' =>
'emailto',
77 'id' =>
'mw-emailuser-recipient',
81 'default' => $this->mTargetObj->getName(),
85 'default' => $this->
msg(
'defemailsubject',
87 'label-message' =>
'emailsubject',
95 'label-message' =>
'emailmessage',
100 'label-message' =>
'emailccme',
101 'default' => $this->
getUser()->getBoolOption(
'ccmeonemails' ),
109 $out->addModuleStyles(
'mediawiki.special' );
111 $this->mTarget = $par ?? $request->getVal(
'wpTarget', $request->getVal(
'target',
'' ) );
114 $request->setVal(
'wpTarget', $this->mTarget );
134 case 'blockedemailuser':
136 case 'actionthrottledtext':
139 case 'usermaildisabled':
143 list(
$title, $msg, $params ) = $error;
158 if ( !$this->mTargetObj instanceof
User ) {
173 if ( $target ==
'' ) {
182 return $error ?: $nu;
194 if ( !$target instanceof
User || !$target->
getId() ) {
195 wfDebug(
"Target is invalid user." );
200 if ( !$target->isEmailConfirmed() ) {
201 wfDebug(
"User has no valid email." );
206 if ( !$target->canReceiveEmail() ) {
207 wfDebug(
"User does not allow user emails." );
209 return 'nowikiemail';
212 if ( !$target->getOption(
'email-allow-new-users' ) && $sender->
isNewbie() ) {
213 wfDebug(
"User does not allow user emails from new users." );
215 return 'nowikiemail';
218 $muteList = $target->getOption(
'email-blacklist',
'' );
220 $muteList = MultiUsernameFilter::splitIds( $muteList );
221 $lookup = CentralIdLookup::factory();
222 $senderId = $lookup->centralIdFromLocalUser( $sender );
223 if ( $senderId !== 0 && in_array( $senderId, $muteList ) ) {
224 wfDebug(
"User does not allow user emails from this user." );
226 return 'nowikiemail';
243 if ( $config ===
null ) {
244 wfDebug( __METHOD__ .
' called without a Config instance passed to it' );
245 $config = MediaWikiServices::getInstance()->getMainConfig();
247 if ( !$config->get(
'EnableEmail' ) || !$config->get(
'EnableUserEmail' ) ) {
248 return 'usermaildisabled';
252 if ( !$user->isEmailConfirmed() ) {
253 return 'mailnologin';
256 if ( !MediaWikiServices::getInstance()
258 ->userHasRight( $user,
'sendemail' )
263 if ( $user->isBlockedFromEmailuser() ) {
264 wfDebug(
"User is blocked from sending e-mail." );
266 return "blockedemailuser";
271 if ( $user->pingLimiter(
'emailuser', 0 ) ) {
272 wfDebug(
"Ping limiter triggered." );
274 return 'actionthrottledtext';
279 Hooks::runner()->onUserCanSendEmail( $user, $hookErr );
280 Hooks::runner()->onEmailUserPermissionsErrors( $user, $editToken, $hookErr );
295 $htmlForm = HTMLForm::factory(
'ooui', [
300 'label' => $this->
msg(
'emailusername' )->text(),
301 'id' =>
'emailusertarget',
308 ->setSubmitCallback( [ $this,
'sendEmailForm' ] )
309 ->setFormIdentifier(
'userForm' )
310 ->setId(
'askusername' )
311 ->setWrapperLegendMsg(
'emailtarget' )
312 ->setSubmitTextMsg(
'emailusernamesubmit' )
320 if ( !$ret instanceof
User ) {
321 if ( $this->mTarget !=
'' ) {
323 $ret = ( $ret ==
'notarget' ) ?
'emailnotarget' : ( $ret .
'text' );
324 return Status::newFatal( $ret );
332 ->addPreText( $this->
msg(
'emailpagetext', $this->mTarget )->parse() )
333 ->setSubmitTextMsg(
'emailsend' )
334 ->setSubmitCallback( [ __CLASS__,
'submit' ] )
335 ->setFormIdentifier(
'sendEmailForm' )
336 ->setWrapperLegendMsg(
'email-legend' )
339 if ( !$this->
getHookRunner()->onEmailUserForm( $htmlForm ) ) {
343 $result = $htmlForm->show();
345 if ( $result ===
true || ( $result instanceof
Status && $result->
isGood() ) ) {
346 $out->setPageTitle( $this->
msg(
'emailsent' ) );
347 $out->addWikiMsg(
'emailsenttext', $this->mTarget );
348 $out->returnToMain(
false, $ret->getUserPage() );
366 if ( !$target instanceof
User ) {
368 return Status::newFatal( $target .
'text' );
371 $to = MailAddress::newFromUser( $target );
372 $from = MailAddress::newFromUser( $context->
getUser() );
373 $subject = $data[
'Subject'];
374 $text = $data[
'Text'];
377 $text = rtrim( $text ) .
"\n\n-- \n";
378 $text .= $context->
msg(
'emailuserfooter',
379 $from->name, $to->name )->inContentLanguage()->text();
381 if ( $config->get(
'EnableSpecialMute' ) ) {
383 $text .=
"\n" . $context->
msg(
384 'specialmute-email-footer',
385 $specialMutePage->getCanonicalURL(),
387 )->inContentLanguage()->text();
391 if ( $context->
getUser()->pingLimiter(
'emailuser' ) ) {
396 if ( !Hooks::runner()->onEmailUser( $to, $from, $subject, $text, $error ) ) {
397 if ( $error instanceof
Status ) {
399 } elseif ( $error ===
false || $error ===
'' || $error === [] ) {
402 } elseif ( $error ===
true ) {
404 return Status::newGood();
405 } elseif ( is_array( $error ) ) {
406 $status = Status::newGood();
407 foreach ( $error as $e ) {
408 $status->fatal( $e );
412 return Status::newFatal( $error );
416 $type = is_object( $error ) ? get_class( $error ) : gettype( $error );
418 "this is deprecated since MediaWiki 1.29",
419 '1.29',
false,
false );
426 if ( $config->get(
'UserEmailUseReplyTo' ) ) {
435 $mailFrom =
new MailAddress( $config->get(
'PasswordSender' ),
436 $context->
msg(
'emailsender' )->inContentLanguage()->text() );
458 $status = UserMailer::send( $to, $mailFrom, $subject, $text, [
459 'replyTo' => $replyTo,
462 if ( !$status->isGood() ) {
468 if ( $data[
'CCMe'] && $to != $from ) {
471 $ccSubject = $context->
msg(
'emailccsubject' )->plaintextParams(
472 $target->getName(), $subject )->text();
475 Hooks::runner()->onEmailUserCC( $ccTo, $ccFrom, $ccSubject, $ccText );
477 if ( $config->get(
'UserEmailUseReplyTo' ) ) {
479 $config->get(
'PasswordSender' ),
480 $context->
msg(
'emailsender' )->inContentLanguage()->text()
488 $ccStatus = UserMailer::send(
489 $ccTo, $mailFrom, $ccSubject, $ccText, [
490 'replyTo' => $replyTo,
492 $status->merge( $ccStatus );
495 Hooks::runner()->onEmailUserComplete( $to, $from, $subject, $text );
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfDeprecatedMsg( $msg, $version=false, $component=false, $callerOffset=2)
Log a deprecation warning with arbitrary message text.
Extension of RawMessage implementing IApiMessage @newable.
An IContextSource implementation which will inherit context from another source but allow individual ...
An error page which can definitely be safely rendered using the OutputPage.
Stores a single person's name and email address.
Show an error when a user tries to do something they do not have the necessary permissions for.
A special page that allows users to send e-mails to other users.
static getTarget( $target, User $sender)
Validate target User.
userForm( $name)
Form to ask for target user name.
static getPermissionsError( $user, $editToken, Config $config=null)
Check whether a user is allowed to send email.
static validateTarget( $target, User $sender)
Validate target User.
static submit(array $data, IContextSource $context)
Really send a mail.
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
doesWrites()
Indicates whether this special page may perform database writes.
getDescription()
Returns the name that goes in the <h1> in the special page itself, and also the name that will be l...
execute( $par)
Default execute method Checks user permissions.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setContext( $context)
Sets the context this SpecialPage is executed in.
getName()
Get the name of this Special Page.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!...
getOutput()
Get the OutputPage being used for this instance.
getUser()
Shortcut to get the User executing this instance.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
getPageTitle( $subpage=false)
Get a self-referential title object.
MediaWiki Linker LinkRenderer null $linkRenderer
isGood()
Returns whether the operation completed and didn't have any error or warnings.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Show an error when the user hits a rate limit.
Shortcut to construct a special page which is unlisted by default.
Show an error when the user tries to do something whilst blocked.
static search( $audience, $search, $limit, $offset=0)
Do a prefix search of user names and return a list of matching user names.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
getId()
Get the user's ID.
isNewbie()
Determine whether the user is a newbie.
Interface for configuration instances.
Interface for objects which can provide a MediaWiki context on request.
getConfig()
Get the site configuration.
msg( $key,... $params)
This is the method for getting translated interface messages.