diff --git a/src/applications/metamta/query/PhabricatorMetaMTAMemberQuery.php b/src/applications/metamta/query/PhabricatorMetaMTAMemberQuery.php index e06da5f4e3..8657981836 100644 --- a/src/applications/metamta/query/PhabricatorMetaMTAMemberQuery.php +++ b/src/applications/metamta/query/PhabricatorMetaMTAMemberQuery.php @@ -24,6 +24,8 @@ final class PhabricatorMetaMTAMemberQuery extends PhabricatorQuery { } public function execute() { + $viewer = $this->getViewer(); + $phids = array_fuse($this->phids); $actors = array(); $type_map = array(); @@ -33,6 +35,33 @@ final class PhabricatorMetaMTAMemberQuery extends PhabricatorQuery { // TODO: Generalize this somewhere else. + + // If we have packages, break them down into their constituent user and + // project owners first. Then we'll resolve those and build the packages + // back up from the pieces. + $package_type = PhabricatorOwnersPackagePHIDType::TYPECONST; + $package_phids = idx($type_map, $package_type, array()); + unset($type_map[$package_type]); + + $package_map = array(); + if ($package_phids) { + $packages = id(new PhabricatorOwnersPackageQuery()) + ->setViewer($viewer) + ->withPHIDs($package_phids) + ->execute(); + + foreach ($packages as $package) { + $package_owners = array(); + foreach ($package->getOwners() as $owner) { + $owner_phid = $owner->getUserPHID(); + $owner_type = phid_get_type($owner_phid); + $type_map[$owner_type][] = $owner_phid; + $package_owners[] = $owner_phid; + } + $package_map[$package->getPHID()] = $package_owners; + } + } + $results = array(); foreach ($type_map as $type => $phids) { switch ($type) { @@ -40,7 +69,7 @@ final class PhabricatorMetaMTAMemberQuery extends PhabricatorQuery { // NOTE: We're loading the projects here in order to respect policies. $projects = id(new PhabricatorProjectQuery()) - ->setViewer($this->getViewer()) + ->setViewer($viewer) ->withPHIDs($phids) ->needMembers(true) ->needWatchers(true) @@ -96,6 +125,21 @@ final class PhabricatorMetaMTAMemberQuery extends PhabricatorQuery { } } + // For any packages, stitch them back together from the resolved users + // and projects. + if ($package_map) { + foreach ($package_map as $package_phid => $owner_phids) { + $resolved = array(); + foreach ($owner_phids as $owner_phid) { + $resolved_phids = idx($results, $owner_phid, array()); + foreach ($resolved_phids as $resolved_phid) { + $resolved[] = $resolved_phid; + } + } + $results[$package_phid] = $resolved; + } + } + return $results; } diff --git a/src/applications/metamta/replyhandler/PhabricatorMailTarget.php b/src/applications/metamta/replyhandler/PhabricatorMailTarget.php index e7e79c5ef9..c607087b22 100644 --- a/src/applications/metamta/replyhandler/PhabricatorMailTarget.php +++ b/src/applications/metamta/replyhandler/PhabricatorMailTarget.php @@ -107,11 +107,15 @@ final class PhabricatorMailTarget extends Phobject { $cc_handles = iterator_to_array($cc_handles); $body = ''; + if ($to_handles) { - $body .= "To: ".implode(', ', mpull($to_handles, 'getName'))."\n"; + $to_names = mpull($to_handles, 'getCommandLineObjectName'); + $body .= "To: ".implode(', ', $to_names)."\n"; } + if ($cc_handles) { - $body .= "Cc: ".implode(', ', mpull($cc_handles, 'getName'))."\n"; + $cc_names = mpull($cc_handles, 'getCommandLineObjectName'); + $body .= "Cc: ".implode(', ', $cc_names)."\n"; } return $body; diff --git a/src/applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php b/src/applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php index 5fa7492fef..2e0e03bb3c 100644 --- a/src/applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php +++ b/src/applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php @@ -8,7 +8,7 @@ final class PhabricatorMetaMTAMailableDatasource } public function getPlaceholderText() { - return pht('Type a user, project, or mailing list name...'); + return pht('Type a user, project, package, or mailing list name...'); } public function getDatasourceApplicationClass() { @@ -19,6 +19,7 @@ final class PhabricatorMetaMTAMailableDatasource return array( new PhabricatorPeopleDatasource(), new PhabricatorProjectDatasource(), + new PhabricatorOwnersPackageDatasource(), ); } diff --git a/src/applications/owners/controller/PhabricatorOwnersPathsController.php b/src/applications/owners/controller/PhabricatorOwnersPathsController.php index 55aeb11b60..d1d6de760d 100644 --- a/src/applications/owners/controller/PhabricatorOwnersPathsController.php +++ b/src/applications/owners/controller/PhabricatorOwnersPathsController.php @@ -64,7 +64,7 @@ final class PhabricatorOwnersPathsController $editor->applyTransactions($package, $xactions); return id(new AphrontRedirectResponse()) - ->setURI('/owners/package/'.$package->getID().'/'); + ->setURI($package->getURI()); } else { $paths = $package->getPaths(); $path_refs = mpull($paths, 'getRef'); @@ -106,7 +106,7 @@ final class PhabricatorOwnersPathsController require_celerity_resource('owners-path-editor-css'); - $cancel_uri = '/owners/package/'.$package->getID().'/'; + $cancel_uri = $package->getURI(); $form = id(new AphrontFormView()) ->setUser($viewer) diff --git a/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php b/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php index fc97be6fce..7f705ec13d 100644 --- a/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php +++ b/src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php @@ -51,8 +51,7 @@ final class PhabricatorOwnersPackageEditEngine } protected function getObjectViewURI($object) { - $id = $object->getID(); - return "/owners/package/{$id}/"; + return $object->getURI(); } protected function buildCustomEditFields($object) { diff --git a/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php b/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php index 52f30e0994..f9267a0ba9 100644 --- a/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php +++ b/src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php @@ -346,8 +346,7 @@ final class PhabricatorOwnersPackageTransactionEditor $body = parent::buildMailBody($object, $xactions); - $detail_uri = PhabricatorEnv::getProductionURI( - '/owners/package/'.$object->getID().'/'); + $detail_uri = PhabricatorEnv::getProductionURI($object->getURI()); $body->addLinkSection( pht('PACKAGE DETAIL'), diff --git a/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php b/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php index 772bb84fc0..cb23ca4041 100644 --- a/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php +++ b/src/applications/owners/phid/PhabricatorOwnersPackagePHIDType.php @@ -39,12 +39,13 @@ final class PhabricatorOwnersPackagePHIDType extends PhabricatorPHIDType { $monogram = $package->getMonogram(); $name = $package->getName(); $id = $package->getID(); + $uri = $package->getURI(); $handle ->setName($monogram) ->setFullName("{$monogram}: {$name}") ->setCommandLineObjectName("{$monogram} {$name}") - ->setURI("/owners/package/{$id}/"); + ->setURI($uri); if ($package->isArchived()) { $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED); diff --git a/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php b/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php index e74d3c6a63..728c3f42a8 100644 --- a/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php +++ b/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php @@ -138,7 +138,7 @@ final class PhabricatorOwnersPackageSearchEngine ->setObject($package) ->setObjectName($package->getMonogram()) ->setHeader($package->getName()) - ->setHref('/owners/package/'.$id.'/'); + ->setHref($package->getURI()); if ($package->isArchived()) { $item->setDisabled(true); diff --git a/src/applications/owners/storage/PhabricatorOwnersPackage.php b/src/applications/owners/storage/PhabricatorOwnersPackage.php index 83c007e170..14eb618c30 100644 --- a/src/applications/owners/storage/PhabricatorOwnersPackage.php +++ b/src/applications/owners/storage/PhabricatorOwnersPackage.php @@ -293,6 +293,10 @@ final class PhabricatorOwnersPackage return 'O'.$this->getID(); } + public function getURI() { + // TODO: Move these to "/O123" for consistency. + return '/owners/package/'.$this->getID().'/'; + } /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php b/src/applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php index 9230ce270e..41d5d6823a 100644 --- a/src/applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php +++ b/src/applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php @@ -27,9 +27,12 @@ final class PhabricatorOwnersPackageDatasource $packages = $this->executeQuery($query); foreach ($packages as $package) { + $name = $package->getName(); + $monogram = $package->getMonogram(); + $results[] = id(new PhabricatorTypeaheadResult()) - ->setName($package->getName()) - ->setURI('/owners/package/'.$package->getID().'/') + ->setName("{$monogram}: {$name}") + ->setURI($package->getURI()) ->setPHID($package->getPHID()); }