Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / settings / panel / PhabricatorEmailAddressesSettingsPanel.php
blob8f7f633e7e1194c3e01b9c166e54e0a91baf9784
1 <?php
3 final class PhabricatorEmailAddressesSettingsPanel
4 extends PhabricatorSettingsPanel {
6 public function getPanelKey() {
7 return 'email';
10 public function getPanelName() {
11 return pht('Email Addresses');
14 public function getPanelMenuIcon() {
15 return 'fa-at';
18 public function getPanelGroupKey() {
19 return PhabricatorSettingsEmailPanelGroup::PANELGROUPKEY;
22 public function isEditableByAdministrators() {
23 if ($this->getUser()->getIsMailingList()) {
24 return true;
27 return false;
30 public function processRequest(AphrontRequest $request) {
31 $user = $this->getUser();
32 $editable = PhabricatorEnv::getEnvConfig('account.editable');
34 $uri = new PhutilURI($request->getPath());
36 if ($editable) {
37 $new = $request->getStr('new');
38 if ($new) {
39 return $this->returnNewAddressResponse($request, $uri, $new);
42 $delete = $request->getInt('delete');
43 if ($delete) {
44 return $this->returnDeleteAddressResponse($request, $uri, $delete);
48 $verify = $request->getInt('verify');
49 if ($verify) {
50 return $this->returnVerifyAddressResponse($request, $uri, $verify);
53 $primary = $request->getInt('primary');
54 if ($primary) {
55 return $this->returnPrimaryAddressResponse($request, $uri, $primary);
58 $emails = id(new PhabricatorUserEmail())->loadAllWhere(
59 'userPHID = %s ORDER BY address',
60 $user->getPHID());
62 $rowc = array();
63 $rows = array();
64 foreach ($emails as $email) {
66 $button_verify = javelin_tag(
67 'a',
68 array(
69 'class' => 'button small button-grey',
70 'href' => $uri->alter('verify', $email->getID()),
71 'sigil' => 'workflow',
73 pht('Verify'));
75 $button_make_primary = javelin_tag(
76 'a',
77 array(
78 'class' => 'button small button-grey',
79 'href' => $uri->alter('primary', $email->getID()),
80 'sigil' => 'workflow',
82 pht('Make Primary'));
84 $button_remove = javelin_tag(
85 'a',
86 array(
87 'class' => 'button small button-grey',
88 'href' => $uri->alter('delete', $email->getID()),
89 'sigil' => 'workflow',
91 pht('Remove'));
93 $button_primary = phutil_tag(
94 'a',
95 array(
96 'class' => 'button small disabled',
98 pht('Primary'));
100 if (!$email->getIsVerified()) {
101 $action = $button_verify;
102 } else if ($email->getIsPrimary()) {
103 $action = $button_primary;
104 } else {
105 $action = $button_make_primary;
108 if ($email->getIsPrimary()) {
109 $remove = $button_primary;
110 $rowc[] = 'highlighted';
111 } else {
112 $remove = $button_remove;
113 $rowc[] = null;
116 $rows[] = array(
117 $email->getAddress(),
118 $action,
119 $remove,
123 $table = new AphrontTableView($rows);
124 $table->setHeaders(
125 array(
126 pht('Email'),
127 pht('Status'),
128 pht('Remove'),
130 $table->setColumnClasses(
131 array(
132 'wide',
133 'action',
134 'action',
136 $table->setRowClasses($rowc);
137 $table->setColumnVisibility(
138 array(
139 true,
140 true,
141 $editable,
144 $buttons = array();
145 if ($editable) {
146 $buttons[] = id(new PHUIButtonView())
147 ->setTag('a')
148 ->setIcon('fa-plus')
149 ->setText(pht('Add New Address'))
150 ->setHref($uri->alter('new', 'true'))
151 ->addSigil('workflow')
152 ->setColor(PHUIButtonView::GREY);
155 return $this->newBox(pht('Email Addresses'), $table, $buttons);
158 private function returnNewAddressResponse(
159 AphrontRequest $request,
160 PhutilURI $uri,
161 $new) {
163 $user = $this->getUser();
164 $viewer = $this->getViewer();
166 $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
167 $viewer,
168 $request,
169 $this->getPanelURI());
171 $e_email = true;
172 $email = null;
173 $errors = array();
174 if ($request->isDialogFormPost()) {
175 $email = trim($request->getStr('email'));
177 if ($new == 'verify') {
178 // The user clicked "Done" from the "an email has been sent" dialog.
179 return id(new AphrontReloadResponse())->setURI($uri);
182 PhabricatorSystemActionEngine::willTakeAction(
183 array($viewer->getPHID()),
184 new PhabricatorSettingsAddEmailAction(),
187 if (!strlen($email)) {
188 $e_email = pht('Required');
189 $errors[] = pht('Email is required.');
190 } else if (!PhabricatorUserEmail::isValidAddress($email)) {
191 $e_email = pht('Invalid');
192 $errors[] = PhabricatorUserEmail::describeValidAddresses();
193 } else if (!PhabricatorUserEmail::isAllowedAddress($email)) {
194 $e_email = pht('Disallowed');
195 $errors[] = PhabricatorUserEmail::describeAllowedAddresses();
197 if ($e_email === true) {
198 $application_email = id(new PhabricatorMetaMTAApplicationEmailQuery())
199 ->setViewer(PhabricatorUser::getOmnipotentUser())
200 ->withAddresses(array($email))
201 ->executeOne();
202 if ($application_email) {
203 $e_email = pht('In Use');
204 $errors[] = $application_email->getInUseMessage();
208 if (!$errors) {
209 $object = id(new PhabricatorUserEmail())
210 ->setAddress($email)
211 ->setIsVerified(0);
213 // If an administrator is editing a mailing list, automatically verify
214 // the address.
215 if ($viewer->getPHID() != $user->getPHID()) {
216 if ($viewer->getIsAdmin()) {
217 $object->setIsVerified(1);
221 try {
222 id(new PhabricatorUserEditor())
223 ->setActor($viewer)
224 ->addEmail($user, $object);
226 if ($object->getIsVerified()) {
227 // If we autoverified the address, just reload the page.
228 return id(new AphrontReloadResponse())->setURI($uri);
231 $object->sendVerificationEmail($user);
233 $dialog = $this->newDialog()
234 ->addHiddenInput('new', 'verify')
235 ->setTitle(pht('Verification Email Sent'))
236 ->appendChild(phutil_tag('p', array(), pht(
237 'A verification email has been sent. Click the link in the '.
238 'email to verify your address.')))
239 ->setSubmitURI($uri)
240 ->addSubmitButton(pht('Done'));
242 return id(new AphrontDialogResponse())->setDialog($dialog);
243 } catch (AphrontDuplicateKeyQueryException $ex) {
244 $e_email = pht('Duplicate');
245 $errors[] = pht('Another user already has this email.');
250 if ($errors) {
251 $errors = id(new PHUIInfoView())
252 ->setErrors($errors);
255 $form = id(new PHUIFormLayoutView())
256 ->appendChild(
257 id(new AphrontFormTextControl())
258 ->setLabel(pht('Email'))
259 ->setName('email')
260 ->setValue($email)
261 ->setCaption(PhabricatorUserEmail::describeAllowedAddresses())
262 ->setError($e_email));
264 $dialog = $this->newDialog()
265 ->addHiddenInput('new', 'true')
266 ->setTitle(pht('New Address'))
267 ->appendChild($errors)
268 ->appendChild($form)
269 ->addSubmitButton(pht('Save'))
270 ->addCancelButton($uri);
272 return id(new AphrontDialogResponse())->setDialog($dialog);
275 private function returnDeleteAddressResponse(
276 AphrontRequest $request,
277 PhutilURI $uri,
278 $email_id) {
279 $user = $this->getUser();
280 $viewer = $this->getViewer();
282 $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
283 $viewer,
284 $request,
285 $this->getPanelURI());
287 // NOTE: You can only delete your own email addresses, and you can not
288 // delete your primary address.
289 $email = id(new PhabricatorUserEmail())->loadOneWhere(
290 'id = %d AND userPHID = %s AND isPrimary = 0',
291 $email_id,
292 $user->getPHID());
294 if (!$email) {
295 return new Aphront404Response();
298 if ($request->isFormPost()) {
299 id(new PhabricatorUserEditor())
300 ->setActor($viewer)
301 ->removeEmail($user, $email);
303 return id(new AphrontRedirectResponse())->setURI($uri);
306 $address = $email->getAddress();
308 $dialog = id(new AphrontDialogView())
309 ->setUser($viewer)
310 ->addHiddenInput('delete', $email_id)
311 ->setTitle(pht("Really delete address '%s'?", $address))
312 ->appendParagraph(
313 pht(
314 'Are you sure you want to delete this address? You will no '.
315 'longer be able to use it to login.'))
316 ->appendParagraph(
317 pht(
318 'Note: Removing an email address from your account will invalidate '.
319 'any outstanding password reset links.'))
320 ->addSubmitButton(pht('Delete'))
321 ->addCancelButton($uri);
323 return id(new AphrontDialogResponse())->setDialog($dialog);
326 private function returnVerifyAddressResponse(
327 AphrontRequest $request,
328 PhutilURI $uri,
329 $email_id) {
330 $user = $this->getUser();
331 $viewer = $this->getViewer();
333 // NOTE: You can only send more email for your unverified addresses.
334 $email = id(new PhabricatorUserEmail())->loadOneWhere(
335 'id = %d AND userPHID = %s AND isVerified = 0',
336 $email_id,
337 $user->getPHID());
339 if (!$email) {
340 return new Aphront404Response();
343 if ($request->isFormPost()) {
344 $email->sendVerificationEmail($user);
345 return id(new AphrontRedirectResponse())->setURI($uri);
348 $address = $email->getAddress();
350 $dialog = id(new AphrontDialogView())
351 ->setUser($viewer)
352 ->addHiddenInput('verify', $email_id)
353 ->setTitle(pht('Send Another Verification Email?'))
354 ->appendChild(phutil_tag('p', array(), pht(
355 'Send another copy of the verification email to %s?',
356 $address)))
357 ->addSubmitButton(pht('Send Email'))
358 ->addCancelButton($uri);
360 return id(new AphrontDialogResponse())->setDialog($dialog);
363 private function returnPrimaryAddressResponse(
364 AphrontRequest $request,
365 PhutilURI $uri,
366 $email_id) {
367 $user = $this->getUser();
368 $viewer = $this->getViewer();
370 $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
371 $viewer,
372 $request,
373 $this->getPanelURI());
375 // NOTE: You can only make your own verified addresses primary.
376 $email = id(new PhabricatorUserEmail())->loadOneWhere(
377 'id = %d AND userPHID = %s AND isVerified = 1 AND isPrimary = 0',
378 $email_id,
379 $user->getPHID());
381 if (!$email) {
382 return new Aphront404Response();
385 if ($request->isFormPost()) {
386 id(new PhabricatorUserEditor())
387 ->setActor($viewer)
388 ->changePrimaryEmail($user, $email);
390 return id(new AphrontRedirectResponse())->setURI($uri);
393 $address = $email->getAddress();
395 $dialog = id(new AphrontDialogView())
396 ->setUser($viewer)
397 ->addHiddenInput('primary', $email_id)
398 ->setTitle(pht('Change primary email address?'))
399 ->appendParagraph(
400 pht(
401 'If you change your primary address, Phabricator will send all '.
402 'email to %s.',
403 $address))
404 ->appendParagraph(
405 pht(
406 'Note: Changing your primary email address will invalidate any '.
407 'outstanding password reset links.'))
408 ->addSubmitButton(pht('Change Primary Address'))
409 ->addCancelButton($uri);
411 return id(new AphrontDialogResponse())->setDialog($dialog);