@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 158 lines 4.6 kB view raw
1<?php 2 3final class PhabricatorSubscriptionsCurtainExtension 4 extends PHUICurtainExtension { 5 6 const EXTENSIONKEY = 'subscriptions.subscribers'; 7 8 public function shouldEnableForObject($object) { 9 return ($object instanceof PhabricatorSubscribableInterface); 10 } 11 12 public function getExtensionApplication() { 13 return new PhabricatorSubscriptionsApplication(); 14 } 15 16 public function buildCurtainPanel($object) { 17 $viewer = $this->getViewer(); 18 $viewer_phid = $viewer->getPHID(); 19 $object_phid = $object->getPHID(); 20 21 $max_handles = 100; 22 $max_visible = 8; 23 24 // TODO: We should limit the number of subscriber PHIDs we'll load, so 25 // we degrade gracefully when objects have thousands of subscribers. 26 27 $subscriber_phids = PhabricatorSubscribersQuery::loadSubscribersForPHID( 28 $object_phid); 29 $subscriber_count = count($subscriber_phids); 30 31 $subscriber_phids = $this->sortSubscriberPHIDs( 32 $subscriber_phids, 33 null); 34 35 // If we have fewer subscribers than the maximum number of handles we're 36 // willing to load, load all the handles and then sort the list based on 37 // complete handle data. 38 39 // If we have too many PHIDs, we'll skip this step and accept a less 40 // useful ordering. 41 $handles = null; 42 if ($subscriber_count <= $max_handles) { 43 $handles = $viewer->loadHandles($subscriber_phids); 44 45 $subscriber_phids = $this->sortSubscriberPHIDs( 46 $subscriber_phids, 47 $handles); 48 } 49 50 // If we have more PHIDs to show than visible slots, slice the list. 51 if ($subscriber_count > $max_visible) { 52 $visible_phids = array_slice($subscriber_phids, 0, $max_visible - 1); 53 $show_all = true; 54 } else { 55 $visible_phids = $subscriber_phids; 56 $show_all = false; 57 } 58 59 // If we didn't load handles earlier because we had too many PHIDs, 60 // load them now. 61 if ($handles === null) { 62 $handles = $viewer->loadHandles($visible_phids); 63 } 64 65 PhabricatorPolicyFilterSet::loadHandleViewCapabilities( 66 $viewer, 67 $handles, 68 array($object)); 69 70 $ref_list = id(new PHUICurtainObjectRefListView()) 71 ->setViewer($viewer) 72 ->setEmptyMessage(pht('None')); 73 74 foreach ($visible_phids as $phid) { 75 $handle = $handles[$phid]; 76 77 $ref = $ref_list->newObjectRefView() 78 ->setHandle($handle); 79 80 if ($phid === $viewer_phid) { 81 $ref->setHighlighted(true); 82 } 83 84 if ($handle->hasCapabilities()) { 85 if (!$handle->hasViewCapability($object)) { 86 $ref->setExiled(true); 87 } 88 } 89 } 90 91 if ($show_all) { 92 $view_all_uri = urisprintf( 93 '/subscriptions/list/%s/', 94 $object_phid); 95 96 $ref_list->newTailLink() 97 ->setURI($view_all_uri) 98 ->setText(pht('View All %d Subscriber(s)', $subscriber_count)) 99 ->setWorkflow(true); 100 } 101 102 return $this->newPanel() 103 ->setHeaderText(pht('Subscribers')) 104 ->setOrder(20000) 105 ->appendChild($ref_list); 106 } 107 108 private function sortSubscriberPHIDs(array $subscriber_phids, $handles) { 109 110 // Sort subscriber PHIDs with or without handle data. If we have handles, 111 // we can sort results more comprehensively. 112 113 $viewer = $this->getViewer(); 114 115 $user_type = PhabricatorPeopleUserPHIDType::TYPECONST; 116 $viewer_phid = $viewer->getPHID(); 117 118 $type_order_map = array( 119 PhabricatorPeopleUserPHIDType::TYPECONST => 0, 120 PhabricatorProjectProjectPHIDType::TYPECONST => 1, 121 PhabricatorOwnersPackagePHIDType::TYPECONST => 2, 122 ); 123 $default_type_order = count($type_order_map); 124 125 $subscriber_map = array(); 126 foreach ($subscriber_phids as $subscriber_phid) { 127 $is_viewer = ($viewer_phid === $subscriber_phid); 128 129 $subscriber_type = phid_get_type($subscriber_phid); 130 $type_order = idx($type_order_map, $subscriber_type, $default_type_order); 131 132 $sort_name = ''; 133 $is_complete = false; 134 if ($handles) { 135 if (isset($handles[$subscriber_phid])) { 136 $handle = $handles[$subscriber_phid]; 137 if ($handle->isComplete()) { 138 $is_complete = true; 139 140 $sort_name = $handle->getLinkName(); 141 $sort_name = phutil_utf8_strtolower($sort_name); 142 } 143 } 144 } 145 146 $subscriber_map[$subscriber_phid] = id(new PhutilSortVector()) 147 ->addInt($is_viewer ? 0 : 1) 148 ->addInt($is_complete ? 0 : 1) 149 ->addInt($type_order) 150 ->addString($sort_name); 151 } 152 153 $subscriber_map = msortv($subscriber_map, 'getSelf'); 154 155 return array_keys($subscriber_map); 156 } 157 158}