@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 102 lines 3.0 kB view raw
1<?php 2 3final class PhabricatorSubscriptionsEditor extends PhabricatorEditor { 4 5 private $object; 6 7 private $explicitSubscribePHIDs = array(); 8 private $implicitSubscribePHIDs = array(); 9 private $unsubscribePHIDs = array(); 10 11 public function setObject(PhabricatorSubscribableInterface $object) { 12 $this->object = $object; 13 return $this; 14 } 15 16 /** 17 * Add explicit subscribers. These subscribers have explicitly subscribed 18 * (or been subscribed) to the object, and will be added even if they 19 * had previously unsubscribed. 20 * 21 * @param list<string> $phids List of PHIDs to explicitly subscribe. 22 * @return $this 23 */ 24 public function subscribeExplicit(array $phids) { 25 $this->explicitSubscribePHIDs += array_fill_keys($phids, true); 26 return $this; 27 } 28 29 30 /** 31 * Add implicit subscribers. These subscribers have taken some action which 32 * implicitly subscribes them (e.g., adding a comment) but it will be 33 * suppressed if they've previously unsubscribed from the object. 34 * 35 * @param list<string> $phids List of PHIDs to implicitly subscribe. 36 * @return $this 37 */ 38 public function subscribeImplicit(array $phids) { 39 $this->implicitSubscribePHIDs += array_fill_keys($phids, true); 40 return $this; 41 } 42 43 44 /** 45 * Unsubscribe PHIDs and mark them as unsubscribed, so implicit subscriptions 46 * will not resubscribe them. 47 * 48 * @param list<string> $phids List of PHIDs to unsubscribe. 49 * @return $this 50 */ 51 public function unsubscribe(array $phids) { 52 $this->unsubscribePHIDs += array_fill_keys($phids, true); 53 return $this; 54 } 55 56 57 public function save() { 58 if (!$this->object) { 59 throw new PhutilInvalidStateException('setObject'); 60 } 61 $actor = $this->requireActor(); 62 63 $src = $this->object->getPHID(); 64 65 if ($this->implicitSubscribePHIDs) { 66 $unsub = PhabricatorEdgeQuery::loadDestinationPHIDs( 67 $src, 68 PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST); 69 $unsub = array_fill_keys($unsub, true); 70 $this->implicitSubscribePHIDs = array_diff_key( 71 $this->implicitSubscribePHIDs, 72 $unsub); 73 } 74 75 $add = $this->implicitSubscribePHIDs + $this->explicitSubscribePHIDs; 76 $del = $this->unsubscribePHIDs; 77 78 // If a PHID is marked for both subscription and unsubscription, treat 79 // unsubscription as the stronger action. 80 $add = array_diff_key($add, $del); 81 82 if ($add || $del) { 83 $u_type = PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST; 84 $s_type = PhabricatorObjectHasSubscriberEdgeType::EDGECONST; 85 86 $editor = new PhabricatorEdgeEditor(); 87 88 foreach ($add as $phid => $ignored) { 89 $editor->removeEdge($src, $u_type, $phid); 90 $editor->addEdge($src, $s_type, $phid); 91 } 92 93 foreach ($del as $phid => $ignored) { 94 $editor->removeEdge($src, $s_type, $phid); 95 $editor->addEdge($src, $u_type, $phid); 96 } 97 98 $editor->save(); 99 } 100 } 101 102}