62 parent::__construct(
'Emailuser' );
74 if ( !$target instanceof
User ) {
75 return $this->
msg(
'emailuser-title-notarget' )->text();
78 return $this->
msg(
'emailuser-title-target', $target->getName() )->text();
92 'label-message' =>
'emailfrom',
93 'id' =>
'mw-emailuser-sender',
99 $this->mTargetObj->getUserPage(),
100 $this->mTargetObj->getName()
102 'label-message' =>
'emailto',
103 'id' =>
'mw-emailuser-recipient',
107 'default' => $this->mTargetObj->getName(),
111 'default' => $this->
msg(
'defemailsubject', $user->getName() )->inContentLanguage()->text(),
112 'label-message' =>
'emailsubject',
118 'type' =>
'textarea',
120 'label-message' =>
'emailmessage',
125 'label-message' =>
'emailccme',
126 'default' => $this->userOptionsLookup->getBoolOption( $user,
'ccmeonemails' ),
134 $out->addModuleStyles(
'mediawiki.special' );
136 $this->mTarget = $par ?? $request->getVal(
'wpTarget', $request->getVal(
'target',
'' ) );
139 $request->setVal(
'wpTarget', $this->mTarget );
159 case 'blockedemailuser':
161 case 'actionthrottledtext':
164 case 'usermaildisabled':
168 list(
$title, $msg, $params ) = $error;
183 if ( !$this->mTargetObj instanceof
User ) {
198 if ( $target ==
'' ) {
207 return $error ?: $nu;
219 if ( !$target instanceof
User || !$target->
getId() ) {
220 wfDebug(
"Target is invalid user." );
225 if ( !$target->isEmailConfirmed() ) {
226 wfDebug(
"User has no valid email." );
231 if ( !$target->canReceiveEmail() ) {
232 wfDebug(
"User does not allow user emails." );
234 return 'nowikiemail';
237 if ( !$target->getOption(
'email-allow-new-users' ) && $sender->
isNewbie() ) {
238 wfDebug(
"User does not allow user emails from new users." );
240 return 'nowikiemail';
243 $muteList = $target->getOption(
'email-blacklist',
'' );
245 $muteList = MultiUsernameFilter::splitIds( $muteList );
246 $senderId = MediaWikiServices::getInstance()
247 ->getCentralIdLookup()
248 ->centralIdFromLocalUser( $sender );
249 if ( $senderId !== 0 && in_array( $senderId, $muteList ) ) {
250 wfDebug(
"User does not allow user emails from this user." );
252 return 'nowikiemail';
269 if ( $config ===
null ) {
270 wfDebug( __METHOD__ .
' called without a Config instance passed to it' );
271 $config = MediaWikiServices::getInstance()->getMainConfig();
273 if ( !$config->get(
'EnableEmail' ) || !$config->get(
'EnableUserEmail' ) ) {
274 return 'usermaildisabled';
279 if ( !$user->isEmailConfirmed() ) {
280 return 'mailnologin';
283 if ( !MediaWikiServices::getInstance()
284 ->getPermissionManager()
285 ->userHasRight( $user,
'sendemail' )
290 if ( $user->isBlockedFromEmailuser() ) {
291 wfDebug(
"User is blocked from sending e-mail." );
293 return "blockedemailuser";
298 if ( $user->pingLimiter(
'emailuser', 0 ) ) {
299 wfDebug(
"Ping limiter triggered." );
301 return 'actionthrottledtext';
306 Hooks::runner()->onUserCanSendEmail( $user, $hookErr );
307 Hooks::runner()->onEmailUserPermissionsErrors( $user, $editToken, $hookErr );
322 $htmlForm = HTMLForm::factory(
'ooui', [
327 'label' => $this->
msg(
'emailusername' )->text(),
328 'id' =>
'emailusertarget',
335 ->setSubmitCallback( [ $this,
'sendEmailForm' ] )
336 ->setFormIdentifier(
'userForm' )
337 ->setId(
'askusername' )
338 ->setWrapperLegendMsg(
'emailtarget' )
339 ->setSubmitTextMsg(
'emailusernamesubmit' )
347 if ( !$ret instanceof
User ) {
348 if ( $this->mTarget !=
'' ) {
350 $ret = ( $ret ==
'notarget' ) ?
'emailnotarget' : ( $ret .
'text' );
351 return Status::newFatal( $ret );
359 ->addPreText( $this->
msg(
'emailpagetext', $this->mTarget )->parse() )
360 ->setSubmitTextMsg(
'emailsend' )
361 ->setSubmitCallback( [ __CLASS__,
'submit' ] )
362 ->setFormIdentifier(
'sendEmailForm' )
363 ->setWrapperLegendMsg(
'email-legend' )
366 if ( !$this->
getHookRunner()->onEmailUserForm( $htmlForm ) ) {
370 $result = $htmlForm->show();
372 if ( $result ===
true || ( $result instanceof
Status && $result->
isGood() ) ) {
373 $out->setPageTitle( $this->
msg(
'emailsent' ) );
374 $out->addWikiMsg(
'emailsenttext', $this->mTarget );
375 $out->returnToMain(
false, $ret->getUserPage() );
395 if ( !$target instanceof
User ) {
397 return Status::newFatal( $target .
'text' );
400 $toAddress = MailAddress::newFromUser( $target );
401 $fromAddress = MailAddress::newFromUser( $sender );
402 $subject = $data[
'Subject'];
403 $text = $data[
'Text'];
406 $text = rtrim( $text ) .
"\n\n-- \n";
407 $text .= $context->
msg(
411 )->inContentLanguage()->text();
413 if ( $config->get(
'EnableSpecialMute' ) ) {
415 $text .=
"\n" . $context->
msg(
416 'specialmute-email-footer',
417 $specialMutePage->getCanonicalURL(),
419 )->inContentLanguage()->text();
423 if ( $sender->pingLimiter(
'emailuser' ) ) {
430 $emailer = MediaWikiServices::getInstance()->getEmailer();
434 if ( $error instanceof
Status ) {
436 } elseif ( $error ===
false || $error ===
'' || $error === [] ) {
439 } elseif ( $error ===
true ) {
441 return Status::newGood();
442 } elseif ( is_array( $error ) ) {
443 $status = Status::newGood();
444 foreach ( $error as $e ) {
445 $status->fatal( $e );
449 return Status::newFatal( $error );
453 $type = is_object( $error ) ? get_class( $error ) : gettype( $error );
455 'EmailUser hook set $error to unsupported type ' .
$type
460 if ( $config->get(
'UserEmailUseReplyTo' ) ) {
470 $config->get(
'PasswordSender' ),
471 $context->
msg(
'emailsender' )->inContentLanguage()->text()
473 $replyTo = $fromAddress;
490 $mailFrom = $fromAddress;
494 $status = Status::wrap( $emailer->send(
500 [
'replyTo' => $replyTo ]
503 if ( !$status->isGood() ) {
510 if ( $data[
'CCMe'] && $toAddress != $fromAddress ) {
511 $ccTo = $fromAddress;
512 $ccFrom = $fromAddress;
513 $ccSubject = $context->
msg(
'emailccsubject' )->plaintextParams(
521 if ( $config->get(
'UserEmailUseReplyTo' ) ) {
523 $config->get(
'PasswordSender' ),
524 $context->
msg(
'emailsender' )->inContentLanguage()->text()
532 $ccStatus = $emailer->send(
538 [
'replyTo' => $replyTo ]
540 $status->merge( $ccStatus );
557 $search = $this->userNameUtils->getCanonical( $search );
563 return $this->userNamePrefixSearch
564 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
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.
UserNameUtils $userNameUtils
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.
__construct(UserNameUtils $userNameUtils, UserNamePrefixSearch $userNamePrefixSearch, UserOptionsLookup $userOptionsLookup)
UserOptionsLookup $userOptionsLookup
UserNamePrefixSearch $userNamePrefixSearch
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.
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.
LinkRenderer null $linkRenderer
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
HookRunner null $hookRunner
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.
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.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static newFromName( $name, $validate='valid')
isNewbie()
Determine whether the user is a newbie.
getId( $wikiId=self::LOCAL)
Get the user's ID.
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.