3 final class PhabricatorCalendarEventInviteTransaction
4 extends PhabricatorCalendarEventTransactionType
{
6 const TRANSACTIONTYPE
= 'calendar.invite';
8 public function generateOldValue($object) {
9 $status_uninvited = PhabricatorCalendarEventInvitee
::STATUS_UNINVITED
;
11 $invitees = $object->getInvitees();
12 foreach ($invitees as $key => $invitee) {
13 if ($invitee->getStatus() == $status_uninvited) {
14 unset($invitees[$key]);
18 return array_values(mpull($invitees, 'getInviteePHID'));
21 private function generateChangeMap($object, $new_value) {
22 $status_invited = PhabricatorCalendarEventInvitee
::STATUS_INVITED
;
23 $status_uninvited = PhabricatorCalendarEventInvitee
::STATUS_UNINVITED
;
24 $status_attending = PhabricatorCalendarEventInvitee
::STATUS_ATTENDING
;
26 $old = $this->generateOldValue($object);
28 $add = array_diff($new_value, $old);
29 $rem = array_diff($old, $new_value);
32 foreach ($add as $phid) {
33 $map[$phid] = $status_invited;
36 foreach ($rem as $phid) {
37 $map[$phid] = $status_uninvited;
40 // If we're creating this event and the actor is inviting themselves,
41 // mark them as attending.
42 if ($this->isNewObject()) {
43 $acting_phid = $this->getActingAsPHID();
44 if (isset($map[$acting_phid])) {
45 $map[$acting_phid] = $status_attending;
52 public function applyExternalEffects($object, $value) {
53 $map = $this->generateChangeMap($object, $value);
55 $invitees = $object->getInvitees();
56 $invitees = mpull($invitees, null, 'getInviteePHID');
58 foreach ($map as $phid => $status) {
59 $invitee = idx($invitees, $phid);
61 $invitee = id(new PhabricatorCalendarEventInvitee())
62 ->setEventPHID($object->getPHID())
63 ->setInviteePHID($phid)
64 ->setInviterPHID($this->getActingAsPHID());
65 $invitees[] = $invitee;
67 $invitee->setStatus($status)
71 $object->attachInvitees($invitees);
74 public function validateTransactions($object, array $xactions) {
75 $actor = $this->getActor();
79 $old = $object->getInvitees();
80 $old = mpull($old, null, 'getInviteePHID');
81 foreach ($xactions as $xaction) {
82 $new = $xaction->getNewValue();
83 $new = array_fuse($new);
84 $add = array_diff_key($new, $old);
89 // In the UI, we only allow you to invite mailable objects, but there
90 // is no definitive marker for "invitable object" today. Just allow
91 // any valid object to be invited.
92 $objects = id(new PhabricatorObjectQuery())
96 $objects = mpull($objects, null, 'getPHID');
97 foreach ($add as $phid) {
98 if (isset($objects[$phid])) {
102 $errors[] = $this->newInvalidError(
104 'Invitee "%s" identifies an object that does not exist or '.
105 'which you do not have permission to view.',
114 public function getIcon() {
115 return 'fa-user-plus';
118 public function getTitle() {
119 list($add, $rem) = $this->getChanges();
123 '%s invited %s attendee(s): %s.',
124 $this->renderAuthor(),
126 $this->renderHandleList($add));
127 } else if (!$add && $rem) {
129 '%s uninvited %s attendee(s): %s.',
130 $this->renderAuthor(),
132 $this->renderHandleList($rem));
135 '%s invited %s attendee(s): %s; uninvited %s attendee(s): %s.',
136 $this->renderAuthor(),
138 $this->renderHandleList($add),
140 $this->renderHandleList($rem));
144 public function getTitleForFeed() {
145 list($add, $rem) = $this->getChanges();
149 '%s invited %s attendee(s) to %s: %s.',
150 $this->renderAuthor(),
152 $this->renderObject(),
153 $this->renderHandleList($add));
154 } else if (!$add && $rem) {
156 '%s uninvited %s attendee(s) to %s: %s.',
157 $this->renderAuthor(),
159 $this->renderObject(),
160 $this->renderHandleList($rem));
163 '%s updated the invite list for %s, invited %s: %s; '.
165 $this->renderAuthor(),
166 $this->renderObject(),
168 $this->renderHandleList($add),
170 $this->renderHandleList($rem));
174 private function getChanges() {
175 $old = $this->getOldValue();
176 $new = $this->getNewValue();
178 $add = array_diff($new, $old);
179 $rem = array_diff($old, $new);
181 return array(array_fuse($add), array_fuse($rem));