@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
at upstream/main 147 lines 4.0 kB view raw
1<?php 2 3final class ConpherenceThreadParticipantsTransaction 4 extends ConpherenceThreadTransactionType { 5 6 const TRANSACTIONTYPE = 'participants'; 7 8 public function generateOldValue($object) { 9 return $object->getParticipantPHIDs(); 10 } 11 12 public function generateNewValue($object, $value) { 13 $old = $this->generateOldValue($object); 14 return $this->getPHIDList($old, $value); 15 } 16 17 public function applyExternalEffects($object, $value) { 18 $participants = $object->getParticipants(); 19 20 $old = array_keys($participants); 21 $new = $value; 22 23 $add_map = array_fuse(array_diff($new, $old)); 24 $rem_map = array_fuse(array_diff($old, $new)); 25 26 foreach ($rem_map as $phid) { 27 $remove_participant = $participants[$phid]; 28 $remove_participant->delete(); 29 unset($participants[$phid]); 30 } 31 32 foreach ($add_map as $phid) { 33 if (isset($participants[$phid])) { 34 continue; 35 } 36 37 $participants[$phid] = id(new ConpherenceParticipant()) 38 ->setConpherencePHID($object->getPHID()) 39 ->setParticipantPHID($phid) 40 ->setSeenMessageCount(0) 41 ->save(); 42 } 43 44 $object->attachParticipants($participants); 45 } 46 47 public function getTitle() { 48 $old = $this->getOldValue(); 49 $new = $this->getNewValue(); 50 51 $add = array_diff($new, $old); 52 $rem = array_diff($old, $new); 53 54 $author_phid = $this->getAuthorPHID(); 55 56 if ($add && $rem) { 57 return pht( 58 '%s edited participant(s), added %d: %s; removed %d: %s.', 59 $this->renderAuthor(), 60 count($add), 61 $this->renderHandleList($add), 62 count($rem), 63 $this->renderHandleList($rem)); 64 } else if ((in_array($author_phid, $add)) && (count($add) == 1)) { 65 return pht( 66 '%s joined the room.', 67 $this->renderAuthor()); 68 } else if ((in_array($author_phid, $rem)) && (count($rem) == 1)) { 69 return pht( 70 '%s left the room.', 71 $this->renderAuthor()); 72 } else if ($add) { 73 return pht( 74 '%s added %d participant(s): %s.', 75 $this->renderAuthor(), 76 count($add), 77 $this->renderHandleList($add)); 78 } else { 79 return pht( 80 '%s removed %d participant(s): %s.', 81 $this->renderAuthor(), 82 count($rem), 83 $this->renderHandleList($rem)); 84 } 85 } 86 87 public function validateTransactions($object, array $xactions) { 88 $errors = array(); 89 90 foreach ($xactions as $xaction) { 91 $old = $object->getParticipantPHIDs(); 92 93 $new = $xaction->getNewValue(); 94 $new = $this->getPHIDList($old, $new); 95 96 $add_map = array_fuse(array_diff($new, $old)); 97 $rem_map = array_fuse(array_diff($old, $new)); 98 99 foreach ($add_map as $user_phid) { 100 $user = id(new PhabricatorPeopleQuery()) 101 ->setViewer($this->getActor()) 102 ->withPHIDs(array($user_phid)) 103 ->executeOne(); 104 if (!$user) { 105 $errors[] = $this->newInvalidError( 106 pht( 107 'Participant PHID "%s" is not a valid user PHID.', 108 $user_phid)); 109 continue; 110 } 111 } 112 } 113 114 return $errors; 115 } 116 117 public function getRequiredCapabilities( 118 $object, 119 PhabricatorApplicationTransaction $xaction) { 120 121 $old_map = array_fuse($xaction->getOldValue()); 122 $new_map = array_fuse($xaction->getNewValue()); 123 124 $add = array_keys(array_diff_key($new_map, $old_map)); 125 $rem = array_keys(array_diff_key($old_map, $new_map)); 126 127 $actor_phid = $this->getActingAsPHID(); 128 129 $is_join = (($add === array($actor_phid)) && !$rem); 130 $is_leave = (($rem === array($actor_phid)) && !$add); 131 132 if ($is_join) { 133 // Anyone can join a thread they can see. 134 return null; 135 } 136 137 if ($is_leave) { 138 // Anyone can leave a thread. 139 return null; 140 } 141 142 // You need CAN_EDIT to add or remove participants. For additional 143 // discussion, see D17696 and T4411. 144 return PhabricatorPolicyCapability::CAN_EDIT; 145 } 146 147}