MediaWiki REL1_40
SpecialEmailUser.php
Go to the documentation of this file.
1<?php
28
35 protected $mTarget;
36
40 protected $mTargetObj;
41
43 private $userNameUtils;
44
46 private $userNamePrefixSearch;
47
49 private $userOptionsLookup;
50
56 public function __construct(
57 UserNameUtils $userNameUtils,
58 UserNamePrefixSearch $userNamePrefixSearch,
59 UserOptionsLookup $userOptionsLookup
60 ) {
61 parent::__construct( 'Emailuser' );
62 $this->userNameUtils = $userNameUtils;
63 $this->userNamePrefixSearch = $userNamePrefixSearch;
64 $this->userOptionsLookup = $userOptionsLookup;
65 }
66
67 public function doesWrites() {
68 return true;
69 }
70
71 public function getDescription() {
72 $target = self::getTarget( $this->mTarget, $this->getUser() );
73 if ( !$target instanceof User ) {
74 return $this->msg( 'emailuser-title-notarget' )->text();
75 }
76
77 return $this->msg( 'emailuser-title-target', $target->getName() )->text();
78 }
79
80 protected function getFormFields() {
81 $linkRenderer = $this->getLinkRenderer();
82 $user = $this->getUser();
83 return [
84 'From' => [
85 'type' => 'info',
86 'raw' => 1,
87 'default' => $linkRenderer->makeLink(
88 $user->getUserPage(),
89 $user->getName()
90 ),
91 'label-message' => 'emailfrom',
92 'id' => 'mw-emailuser-sender',
93 ],
94 'To' => [
95 'type' => 'info',
96 'raw' => 1,
97 'default' => $linkRenderer->makeLink(
98 $this->mTargetObj->getUserPage(),
99 $this->mTargetObj->getName()
100 ),
101 'label-message' => 'emailto',
102 'id' => 'mw-emailuser-recipient',
103 ],
104 'Target' => [
105 'type' => 'hidden',
106 'default' => $this->mTargetObj->getName(),
107 ],
108 'Subject' => [
109 'type' => 'text',
110 'default' => $this->msg( 'defemailsubject', $user->getName() )->inContentLanguage()->text(),
111 'label-message' => 'emailsubject',
112 'maxlength' => 200,
113 'size' => 60,
114 'required' => true,
115 ],
116 'Text' => [
117 'type' => 'textarea',
118 'rows' => 20,
119 'label-message' => 'emailmessage',
120 'required' => true,
121 ],
122 'CCMe' => [
123 'type' => 'check',
124 'label-message' => 'emailccme',
125 'default' => $this->userOptionsLookup->getBoolOption( $user, 'ccmeonemails' ),
126 ],
127 ];
128 }
129
130 public function execute( $par ) {
131 $out = $this->getOutput();
132 $request = $this->getRequest();
133 $out->addModuleStyles( 'mediawiki.special' );
134
135 $this->mTarget = $par ?? $request->getVal( 'wpTarget', $request->getVal( 'target', '' ) );
136
137 // This needs to be below assignment of $this->mTarget because
138 // getDescription() needs it to determine the correct page title.
139 $this->setHeaders();
140 $this->outputHeader();
141
142 // error out if sending user cannot do this
144 $this->getUser(),
145 $this->getRequest()->getVal( 'wpEditToken' ),
146 $this->getConfig()
147 );
148
149 switch ( $error ) {
150 case null:
151 # Wahey!
152 break;
153 case 'badaccess':
154 throw new PermissionsError( 'sendemail' );
155 case 'blockedemailuser':
156 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null
157 throw new UserBlockedError( $this->getUser()->getBlock() );
158 case 'actionthrottledtext':
159 throw new ThrottledError;
160 case 'mailnologin':
161 case 'usermaildisabled':
162 throw new ErrorPageError( $error, "{$error}text" );
163 default:
164 # It's a hook error
165 [ $title, $msg, $params ] = $error;
166 throw new ErrorPageError( $title, $msg, $params );
167 }
168
169 // A little hack: HTMLForm will check $this->mTarget only, if the form was posted, not
170 // if the user opens Special:EmailUser/Florian (e.g.). So check, if the user did that
171 // and show the "Send email to user" form directly, if so. Show the "enter username"
172 // form, otherwise.
173 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set
174 $this->mTargetObj = self::getTarget( $this->mTarget, $this->getUser() );
175 if ( !$this->mTargetObj instanceof User ) {
176 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable target is set
177 $this->userForm( $this->mTarget );
178 } else {
179 $this->sendEmailForm();
180 }
181 }
182
190 public static function getTarget( $target, User $sender ) {
191 return EmailUser::getTarget( $target, $sender );
192 }
193
202 public static function validateTarget( $target, User $sender ) {
203 return EmailUser::validateTarget( $target, $sender );
204 }
205
215 public static function getPermissionsError( $user, $editToken, Config $config = null ) {
216 return EmailUser::getPermissionsError( $user, $editToken, $config );
217 }
218
224 protected function userForm( $name ) {
225 $htmlForm = HTMLForm::factory( 'ooui', [
226 'Target' => [
227 'type' => 'user',
228 'exists' => true,
229 'required' => true,
230 'label' => $this->msg( 'emailusername' )->text(),
231 'id' => 'emailusertarget',
232 'autofocus' => true,
233 'value' => $name,
234 ]
235 ], $this->getContext() );
236
237 $htmlForm
238 ->setTitle( $this->getPageTitle() ) // Remove subpage
239 ->setSubmitCallback( [ $this, 'sendEmailForm' ] )
240 ->setFormIdentifier( 'userForm' )
241 ->setId( 'askusername' )
242 ->setWrapperLegendMsg( 'emailtarget' )
243 ->setSubmitTextMsg( 'emailusernamesubmit' )
244 ->show();
245 }
246
247 public function sendEmailForm() {
248 $out = $this->getOutput();
249
250 $ret = $this->mTargetObj;
251 if ( !$ret instanceof User ) {
252 if ( $this->mTarget != '' ) {
253 // Messages used here: notargettext, noemailtext, nowikiemailtext
254 $ret = ( $ret == 'notarget' ) ? 'emailnotarget' : ( $ret . 'text' );
255 return Status::newFatal( $ret );
256 }
257 return false;
258 }
259
260 $htmlForm = HTMLForm::factory( 'ooui', $this->getFormFields(), $this->getContext() );
261 // By now we are supposed to be sure that $this->mTarget is a user name
262 $htmlForm
263 ->setTitle( $this->getPageTitle() ) // Remove subpage
264 ->addPreHtml( $this->msg( 'emailpagetext', $this->mTarget )->parse() )
265 ->setSubmitTextMsg( 'emailsend' )
266 ->setSubmitCallback( [ __CLASS__, 'submit' ] )
267 ->setFormIdentifier( 'sendEmailForm' )
268 ->setWrapperLegendMsg( 'email-legend' )
269 ->prepareForm();
270
271 if ( !$this->getHookRunner()->onEmailUserForm( $htmlForm ) ) {
272 return false;
273 }
274
275 $result = $htmlForm->show();
276
277 if ( $result === true || ( $result instanceof Status && $result->isGood() ) ) {
278 $out->setPageTitle( $this->msg( 'emailsent' ) );
279 $out->addWikiMsg( 'emailsenttext', $this->mTarget );
280 $out->returnToMain( false, $ret->getUserPage() );
281 }
282 return true;
283 }
284
295 public static function submit( array $data, IContextSource $context ) {
296 return EmailUser::submit( $data, $context );
297 }
298
307 public function prefixSearchSubpages( $search, $limit, $offset ) {
308 $search = $this->userNameUtils->getCanonical( $search );
309 if ( !$search ) {
310 // No prefix suggestion for invalid user
311 return [];
312 }
313 // Autocomplete subpage as user list - public to allow caching
314 return $this->userNamePrefixSearch
315 ->search( UserNamePrefixSearch::AUDIENCE_PUBLIC, $search, $limit, $offset );
316 }
317
318 protected function getGroupName() {
319 return 'users';
320 }
321}
An error page which can definitely be safely rendered using the OutputPage.
Command for sending emails to users.
Definition EmailUser.php:43
Handles searching prefixes of user names.
UserNameUtils service.
Provides access to user options.
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.
User string $mTargetObj
doesWrites()
Indicates whether this special page may perform database writes.
__construct(UserNameUtils $userNameUtils, UserNamePrefixSearch $userNamePrefixSearch, UserOptionsLookup $userOptionsLookup)
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...
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.
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.
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.
Definition Status.php:46
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.
internal since 1.36
Definition User.php:71
Interface for configuration instances.
Definition Config.php:30
Interface for objects which can provide a MediaWiki context on request.