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

Make packages mailable and subscribable

Summary:
Ref T10939. Fixes T7834.

- Make packages into mailable objects, like projects and users.
- Packages resolve recipients by resolving project and user owners into recipients.

Test Plan:
- Added a comment to a revision with a package subscriber.
- Used `bin/mail show-outbound` to see that owners got mail.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7834, T10939

Differential Revision: https://secure.phabricator.com/D15912

+69 -14
+45 -1
src/applications/metamta/query/PhabricatorMetaMTAMemberQuery.php
··· 24 24 } 25 25 26 26 public function execute() { 27 + $viewer = $this->getViewer(); 28 + 27 29 $phids = array_fuse($this->phids); 28 30 $actors = array(); 29 31 $type_map = array(); ··· 33 35 34 36 // TODO: Generalize this somewhere else. 35 37 38 + 39 + // If we have packages, break them down into their constituent user and 40 + // project owners first. Then we'll resolve those and build the packages 41 + // back up from the pieces. 42 + $package_type = PhabricatorOwnersPackagePHIDType::TYPECONST; 43 + $package_phids = idx($type_map, $package_type, array()); 44 + unset($type_map[$package_type]); 45 + 46 + $package_map = array(); 47 + if ($package_phids) { 48 + $packages = id(new PhabricatorOwnersPackageQuery()) 49 + ->setViewer($viewer) 50 + ->withPHIDs($package_phids) 51 + ->execute(); 52 + 53 + foreach ($packages as $package) { 54 + $package_owners = array(); 55 + foreach ($package->getOwners() as $owner) { 56 + $owner_phid = $owner->getUserPHID(); 57 + $owner_type = phid_get_type($owner_phid); 58 + $type_map[$owner_type][] = $owner_phid; 59 + $package_owners[] = $owner_phid; 60 + } 61 + $package_map[$package->getPHID()] = $package_owners; 62 + } 63 + } 64 + 36 65 $results = array(); 37 66 foreach ($type_map as $type => $phids) { 38 67 switch ($type) { ··· 40 69 // NOTE: We're loading the projects here in order to respect policies. 41 70 42 71 $projects = id(new PhabricatorProjectQuery()) 43 - ->setViewer($this->getViewer()) 72 + ->setViewer($viewer) 44 73 ->withPHIDs($phids) 45 74 ->needMembers(true) 46 75 ->needWatchers(true) ··· 93 122 $results[$phid] = array($phid); 94 123 } 95 124 break; 125 + } 126 + } 127 + 128 + // For any packages, stitch them back together from the resolved users 129 + // and projects. 130 + if ($package_map) { 131 + foreach ($package_map as $package_phid => $owner_phids) { 132 + $resolved = array(); 133 + foreach ($owner_phids as $owner_phid) { 134 + $resolved_phids = idx($results, $owner_phid, array()); 135 + foreach ($resolved_phids as $resolved_phid) { 136 + $resolved[] = $resolved_phid; 137 + } 138 + } 139 + $results[$package_phid] = $resolved; 96 140 } 97 141 } 98 142
+6 -2
src/applications/metamta/replyhandler/PhabricatorMailTarget.php
··· 107 107 $cc_handles = iterator_to_array($cc_handles); 108 108 109 109 $body = ''; 110 + 110 111 if ($to_handles) { 111 - $body .= "To: ".implode(', ', mpull($to_handles, 'getName'))."\n"; 112 + $to_names = mpull($to_handles, 'getCommandLineObjectName'); 113 + $body .= "To: ".implode(', ', $to_names)."\n"; 112 114 } 115 + 113 116 if ($cc_handles) { 114 - $body .= "Cc: ".implode(', ', mpull($cc_handles, 'getName'))."\n"; 117 + $cc_names = mpull($cc_handles, 'getCommandLineObjectName'); 118 + $body .= "Cc: ".implode(', ', $cc_names)."\n"; 115 119 } 116 120 117 121 return $body;
+2 -1
src/applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php
··· 8 8 } 9 9 10 10 public function getPlaceholderText() { 11 - return pht('Type a user, project, or mailing list name...'); 11 + return pht('Type a user, project, package, or mailing list name...'); 12 12 } 13 13 14 14 public function getDatasourceApplicationClass() { ··· 19 19 return array( 20 20 new PhabricatorPeopleDatasource(), 21 21 new PhabricatorProjectDatasource(), 22 + new PhabricatorOwnersPackageDatasource(), 22 23 ); 23 24 } 24 25
+2 -2
src/applications/owners/controller/PhabricatorOwnersPathsController.php
··· 64 64 $editor->applyTransactions($package, $xactions); 65 65 66 66 return id(new AphrontRedirectResponse()) 67 - ->setURI('/owners/package/'.$package->getID().'/'); 67 + ->setURI($package->getURI()); 68 68 } else { 69 69 $paths = $package->getPaths(); 70 70 $path_refs = mpull($paths, 'getRef'); ··· 106 106 107 107 require_celerity_resource('owners-path-editor-css'); 108 108 109 - $cancel_uri = '/owners/package/'.$package->getID().'/'; 109 + $cancel_uri = $package->getURI(); 110 110 111 111 $form = id(new AphrontFormView()) 112 112 ->setUser($viewer)
+1 -2
src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php
··· 51 51 } 52 52 53 53 protected function getObjectViewURI($object) { 54 - $id = $object->getID(); 55 - return "/owners/package/{$id}/"; 54 + return $object->getURI(); 56 55 } 57 56 58 57 protected function buildCustomEditFields($object) {
+1 -2
src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php
··· 346 346 347 347 $body = parent::buildMailBody($object, $xactions); 348 348 349 - $detail_uri = PhabricatorEnv::getProductionURI( 350 - '/owners/package/'.$object->getID().'/'); 349 + $detail_uri = PhabricatorEnv::getProductionURI($object->getURI()); 351 350 352 351 $body->addLinkSection( 353 352 pht('PACKAGE DETAIL'),
+2 -1
src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php
··· 39 39 $monogram = $package->getMonogram(); 40 40 $name = $package->getName(); 41 41 $id = $package->getID(); 42 + $uri = $package->getURI(); 42 43 43 44 $handle 44 45 ->setName($monogram) 45 46 ->setFullName("{$monogram}: {$name}") 46 47 ->setCommandLineObjectName("{$monogram} {$name}") 47 - ->setURI("/owners/package/{$id}/"); 48 + ->setURI($uri); 48 49 49 50 if ($package->isArchived()) { 50 51 $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
+1 -1
src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php
··· 138 138 ->setObject($package) 139 139 ->setObjectName($package->getMonogram()) 140 140 ->setHeader($package->getName()) 141 - ->setHref('/owners/package/'.$id.'/'); 141 + ->setHref($package->getURI()); 142 142 143 143 if ($package->isArchived()) { 144 144 $item->setDisabled(true);
+4
src/applications/owners/storage/PhabricatorOwnersPackage.php
··· 293 293 return 'O'.$this->getID(); 294 294 } 295 295 296 + public function getURI() { 297 + // TODO: Move these to "/O123" for consistency. 298 + return '/owners/package/'.$this->getID().'/'; 299 + } 296 300 297 301 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 298 302
+5 -2
src/applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php
··· 27 27 28 28 $packages = $this->executeQuery($query); 29 29 foreach ($packages as $package) { 30 + $name = $package->getName(); 31 + $monogram = $package->getMonogram(); 32 + 30 33 $results[] = id(new PhabricatorTypeaheadResult()) 31 - ->setName($package->getName()) 32 - ->setURI('/owners/package/'.$package->getID().'/') 34 + ->setName("{$monogram}: {$name}") 35 + ->setURI($package->getURI()) 33 36 ->setPHID($package->getPHID()); 34 37 } 35 38