@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorAuthContactNumberNumberTransaction
4 extends PhabricatorAuthContactNumberTransactionType {
5
6 const TRANSACTIONTYPE = 'number';
7
8 public function generateOldValue($object) {
9 return $object->getContactNumber();
10 }
11
12 public function generateNewValue($object, $value) {
13 $number = new PhabricatorPhoneNumber($value);
14 return $number->toE164();
15 }
16
17 public function applyInternalEffects($object, $value) {
18 $object->setContactNumber($value);
19 }
20
21 public function getTitle() {
22 $old = $this->getOldValue();
23 $new = $this->getNewValue();
24
25 return pht(
26 '%s changed this contact number from %s to %s.',
27 $this->renderAuthor(),
28 $this->renderOldValue(),
29 $this->renderNewValue());
30 }
31
32 public function validateTransactions($object, array $xactions) {
33 $errors = array();
34
35 $current_value = $object->getContactNumber();
36 if ($this->isEmptyTextTransaction($current_value, $xactions)) {
37 $errors[] = $this->newRequiredError(
38 pht('Contact numbers must have a contact number.'));
39 return $errors;
40 }
41
42 $max_length = $object->getColumnMaximumByteLength('contactNumber');
43 foreach ($xactions as $xaction) {
44 $new_value = $xaction->getNewValue();
45 $new_length = strlen($new_value);
46 if ($new_length > $max_length) {
47 $errors[] = $this->newInvalidError(
48 pht(
49 'Contact numbers can not be longer than %s characters.',
50 new PhutilNumber($max_length)),
51 $xaction);
52 continue;
53 }
54
55 try {
56 new PhabricatorPhoneNumber($new_value);
57 } catch (Exception $ex) {
58 $errors[] = $this->newInvalidError(
59 pht(
60 'Contact number is invalid: %s',
61 $ex->getMessage()),
62 $xaction);
63 continue;
64 }
65
66 $new_value = $this->generateNewValue($object, $new_value);
67
68 $unique_key = id(clone $object)
69 ->setContactNumber($new_value)
70 ->newUniqueKey();
71
72 $other = id(new PhabricatorAuthContactNumberQuery())
73 ->setViewer(PhabricatorUser::getOmnipotentUser())
74 ->withUniqueKeys(array($unique_key))
75 ->executeOne();
76
77 if ($other) {
78 if ($other->getID() !== $object->getID()) {
79 $errors[] = $this->newInvalidError(
80 pht('Contact number is already in use.'),
81 $xaction);
82 continue;
83 }
84 }
85
86 $mfa_error = $this->newContactNumberMFAError($object, $xaction);
87 if ($mfa_error) {
88 $errors[] = $mfa_error;
89 continue;
90 }
91 }
92
93 return $errors;
94 }
95
96}