private function getRevisionMatchExplanation($revision_match_data, PhabricatorObjectHandle $obj_handle)
 {
     if (!$revision_match_data) {
         return pht('This commit was made before this feature was built and thus this ' . 'information is unavailable.');
     }
     $body_why = array();
     if ($revision_match_data['usedURI']) {
         return pht('We found a "%s" field with value "%s" in the commit message, ' . 'and the domain on the URI matches this install, so ' . 'we linked this commit to %s.', 'Differential Revision', $revision_match_data['foundURI'], phutil_tag('a', array('href' => $obj_handle->getURI()), $obj_handle->getName()));
     } else {
         if ($revision_match_data['foundURI']) {
             $body_why[] = pht('We found a "%s" field with value "%s" in the commit message, ' . 'but the domain on this URI did not match the configured ' . 'domain for this install, "%s", so we ignored it under ' . 'the assumption that it refers to some third-party revision.', 'Differential Revision', $revision_match_data['foundURI'], $revision_match_data['validDomain']);
         } else {
             $body_why[] = pht('We didn\'t find a "%s" field in the commit message.', 'Differential Revision');
         }
     }
     switch ($revision_match_data['matchHashType']) {
         case ArcanistDifferentialRevisionHash::HASH_GIT_TREE:
             $hash_info = true;
             $hash_type = 'tree';
             break;
         case ArcanistDifferentialRevisionHash::HASH_GIT_COMMIT:
         case ArcanistDifferentialRevisionHash::HASH_MERCURIAL_COMMIT:
             $hash_info = true;
             $hash_type = 'commit';
             break;
         default:
             $hash_info = false;
             break;
     }
     if ($hash_info) {
         $diff_link = phutil_tag('a', array('href' => $obj_handle->getURI()), $obj_handle->getName());
         $body_why = pht('This commit and the active diff of %s had the same %s hash ' . '(%s) so we linked this commit to %s.', $diff_link, $hash_type, $revision_match_data['matchHashValue'], $diff_link);
     }
     return phutil_implode_html("\n", $body_why);
 }
 private function performMerge(ManiphestTask $task, PhabricatorObjectHandle $handle, array $phids)
 {
     $user = $this->getRequest()->getUser();
     $response = id(new AphrontReloadResponse())->setURI($handle->getURI());
     $phids = array_fill_keys($phids, true);
     unset($phids[$task->getPHID()]);
     // Prevent merging a task into itself.
     if (!$phids) {
         return $response;
     }
     $targets = id(new ManiphestTaskQuery())->setViewer($user)->withPHIDs(array_keys($phids))->execute();
     if (empty($targets)) {
         return $response;
     }
     $editor = id(new ManiphestTransactionEditor())->setActor($user)->setContentSourceFromRequest($this->getRequest())->setContinueOnNoEffect(true)->setContinueOnMissingFields(true);
     $cc_vector = array();
     $cc_vector[] = $task->getCCPHIDs();
     foreach ($targets as $target) {
         $cc_vector[] = $target->getCCPHIDs();
         $cc_vector[] = array($target->getAuthorPHID(), $target->getOwnerPHID());
         $merged_into_txn = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_MERGED_INTO)->setNewValue($task->getPHID());
         $editor->applyTransactions($target, array($merged_into_txn));
     }
     $all_ccs = array_mergev($cc_vector);
     $all_ccs = array_filter($all_ccs);
     $all_ccs = array_unique($all_ccs);
     $add_ccs = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_CCS)->setNewValue($all_ccs);
     $merged_from_txn = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_MERGED_FROM)->setNewValue(mpull($targets, 'getPHID'));
     $editor->applyTransactions($task, array($add_ccs, $merged_from_txn));
     return $response;
 }
Esempio n. 3
0
 public function renderBreadcrumbs($slug)
 {
     $ancestor_handles = array();
     $ancestral_slugs = PhabricatorSlug::getAncestry($slug);
     $ancestral_slugs[] = $slug;
     if ($ancestral_slugs) {
         $empty_slugs = array_fill_keys($ancestral_slugs, null);
         $ancestors = id(new PhrictionDocumentQuery())->setViewer($this->getRequest()->getUser())->withSlugs($ancestral_slugs)->execute();
         $ancestors = mpull($ancestors, null, 'getSlug');
         $ancestor_phids = mpull($ancestors, 'getPHID');
         $handles = array();
         if ($ancestor_phids) {
             $handles = $this->loadViewerHandles($ancestor_phids);
         }
         $ancestor_handles = array();
         foreach ($ancestral_slugs as $slug) {
             if (isset($ancestors[$slug])) {
                 $ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()];
             } else {
                 $handle = new PhabricatorObjectHandle();
                 $handle->setName(PhabricatorSlug::getDefaultTitle($slug));
                 $handle->setURI(PhrictionDocument::getSlugURI($slug));
                 $ancestor_handles[] = $handle;
             }
         }
     }
     $breadcrumbs = array();
     foreach ($ancestor_handles as $ancestor_handle) {
         $breadcrumbs[] = id(new PHUICrumbView())->setName($ancestor_handle->getName())->setHref($ancestor_handle->getUri());
     }
     return $breadcrumbs;
 }
 protected function renderObjectRef($object, PhabricatorObjectHandle $handle, $anchor, $id)
 {
     if ($this->getEngine()->isTextMode()) {
         return '#' . $id;
     }
     return $handle->renderTag();
 }
 private function performMerge(ManiphestTask $task, PhabricatorObjectHandle $handle, array $phids)
 {
     $user = $this->getRequest()->getUser();
     $response = id(new AphrontReloadResponse())->setURI($handle->getURI());
     $phids = array_fill_keys($phids, true);
     unset($phids[$task->getPHID()]);
     // Prevent merging a task into itself.
     if (!$phids) {
         return $response;
     }
     $targets = id(new ManiphestTaskQuery())->setViewer($user)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withPHIDs(array_keys($phids))->needSubscriberPHIDs(true)->needProjectPHIDs(true)->execute();
     if (empty($targets)) {
         return $response;
     }
     $editor = id(new ManiphestTransactionEditor())->setActor($user)->setContentSourceFromRequest($this->getRequest())->setContinueOnNoEffect(true)->setContinueOnMissingFields(true);
     $cc_vector = array();
     // since we loaded this via a generic object query, go ahead and get the
     // attach the subscriber and project phids now
     $task->attachSubscriberPHIDs(PhabricatorSubscribersQuery::loadSubscribersForPHID($task->getPHID()));
     $task->attachProjectPHIDs(PhabricatorEdgeQuery::loadDestinationPHIDs($task->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST));
     $cc_vector[] = $task->getSubscriberPHIDs();
     foreach ($targets as $target) {
         $cc_vector[] = $target->getSubscriberPHIDs();
         $cc_vector[] = array($target->getAuthorPHID(), $target->getOwnerPHID());
         $merged_into_txn = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_MERGED_INTO)->setNewValue($task->getPHID());
         $editor->applyTransactions($target, array($merged_into_txn));
     }
     $all_ccs = array_mergev($cc_vector);
     $all_ccs = array_filter($all_ccs);
     $all_ccs = array_unique($all_ccs);
     $add_ccs = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('=' => $all_ccs));
     $merged_from_txn = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_MERGED_FROM)->setNewValue(mpull($targets, 'getPHID'));
     $editor->applyTransactions($task, array($add_ccs, $merged_from_txn));
     return $response;
 }
 private function renderHandleIcon(PhabricatorObjectHandle $handle)
 {
     $ownername = $handle->getName();
     $ownerlink = '/p/' . $ownername . '/';
     $image_uri = 'background-image: url(' . $handle->getImageURI() . ')';
     $sigil = 'has-tooltip';
     $meta = array('tip' => pht($ownername), 'size' => 200, 'align' => 'E');
     $image = id(new SprintHandleIconView())->addSigil($sigil)->setMetadata($meta)->setHref($ownerlink)->setIconStyle($image_uri);
     return $image;
 }
 protected final function getHandle($phid)
 {
     if (isset($this->handles[$phid])) {
         if ($this->handles[$phid] instanceof PhabricatorObjectHandle) {
             return $this->handles[$phid];
         }
     }
     $handle = new PhabricatorObjectHandle();
     $handle->setPHID($phid);
     $handle->setName("Unloaded Object '{$phid}'");
     return $handle;
 }
 protected function getObjectHref($object, PhabricatorObjectHandle $handle, $id)
 {
     $href = $handle->getURI();
     // If the ID has a `M123/456` component, link to that specific image.
     $id = explode('/', $id);
     if (isset($id[1])) {
         $href = $href . '/' . $id[1] . '/';
     }
     if ($this->getEngine()->getConfig('uri.full')) {
         $href = PhabricatorEnv::getURI($href);
     }
     return $href;
 }
 protected function getObjectNameText($object, PhabricatorObjectHandle $handle, $id)
 {
     // If this commit is unreachable, return the handle name instead of the
     // normal text because it may be able to tell the user that the commit
     // was rewritten and where to find the new one.
     // By default, we try to preserve what the user actually typed as
     // faithfully as possible, but if they're referencing a deleted commit
     // it's more valuable to try to pick up any rewrite. See T11522.
     if ($object->isUnreachable()) {
         return $handle->getName();
     }
     return parent::getObjectNameText($object, $handle, $id);
 }
 public function renderHovercard(PhabricatorHovercardView $hovercard, PhabricatorObjectHandle $handle, $commit, $data)
 {
     $viewer = $this->getViewer();
     $author_phid = $commit->getAuthorPHID();
     if ($author_phid) {
         $author = $viewer->renderHandle($author_phid);
     } else {
         $commit_data = $commit->loadCommitData();
         $author = phutil_tag('em', array(), $commit_data->getAuthorName());
     }
     $hovercard->setTitle($handle->getName());
     $hovercard->setDetail($commit->getSummary());
     $hovercard->addField(pht('Author'), $author);
     $hovercard->addField(pht('Date'), phabricator_date($commit->getEpoch(), $viewer));
     if ($commit->getAuditStatus() != PhabricatorAuditCommitStatusConstants::NONE) {
         $hovercard->addField(pht('Audit Status'), PhabricatorAuditCommitStatusConstants::getStatusName($commit->getAuditStatus()));
     }
 }
 public static function newFromHandle(PhabricatorObjectHandle $handle)
 {
     $token = id(new PhabricatorTypeaheadTokenView())->setKey($handle->getPHID())->setValue($handle->getFullName())->setIcon($handle->getIcon());
     if ($handle->isDisabled() || $handle->getStatus() == PhabricatorObjectHandle::STATUS_CLOSED) {
         $token->setTokenType(self::TYPE_DISABLED);
     } else {
         $token->setColor($handle->getTagColor());
     }
     return $token;
 }
Esempio n. 12
0
 protected function createBasicDummyHandle($name, $type, $fullname = null, $uri = null)
 {
     $id = mt_rand(15, 9999);
     $handle = new PhabricatorObjectHandle();
     $handle->setName($name);
     $handle->setType($type);
     $handle->setPHID(PhabricatorPHID::generateNewPHID($type));
     if ($fullname) {
         $handle->setFullName($fullname);
     } else {
         $handle->setFullName(sprintf('%s%d: %s', substr($type, 0, 1), $id, $name));
     }
     if ($uri) {
         $handle->setURI($uri);
     }
     return $handle;
 }
 private function performMerge(ManiphestTask $task, PhabricatorObjectHandle $handle, array $phids)
 {
     $user = $this->getRequest()->getUser();
     $response = id(new AphrontReloadResponse())->setURI($handle->getURI());
     $phids = array_fill_keys($phids, true);
     unset($phids[$task->getPHID()]);
     // Prevent merging a task into itself.
     if (!$phids) {
         return $response;
     }
     $targets = id(new ManiphestTaskQuery())->setViewer($user)->withPHIDs(array_keys($phids))->execute();
     if (empty($targets)) {
         return $response;
     }
     $editor = id(new ManiphestTransactionEditor())->setActor($user)->setContentSourceFromRequest($this->getRequest())->setContinueOnNoEffect(true)->setContinueOnMissingFields(true);
     $task_names = array();
     $merge_into_name = 'T' . $task->getID();
     $cc_vector = array();
     $cc_vector[] = $task->getCCPHIDs();
     foreach ($targets as $target) {
         $cc_vector[] = $target->getCCPHIDs();
         $cc_vector[] = array($target->getAuthorPHID(), $target->getOwnerPHID());
         $close_task = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_STATUS)->setNewValue(ManiphestTaskStatus::getDuplicateStatus());
         $merge_comment = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new ManiphestTransactionComment())->setContent("✘ Merged into {$merge_into_name}."));
         $editor->applyTransactions($target, array($close_task, $merge_comment));
         $task_names[] = 'T' . $target->getID();
     }
     $all_ccs = array_mergev($cc_vector);
     $all_ccs = array_filter($all_ccs);
     $all_ccs = array_unique($all_ccs);
     $task_names = implode(', ', $task_names);
     $add_ccs = id(new ManiphestTransaction())->setTransactionType(ManiphestTransaction::TYPE_CCS)->setNewValue($all_ccs);
     $merged_comment = id(new ManiphestTransaction())->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)->attachComment(id(new ManiphestTransactionComment())->setContent("◀ Merged tasks: {$task_names}."));
     $editor->applyTransactions($task, array($add_ccs, $merged_comment));
     return $response;
 }
 public static function newFromPolicyAndHandle($policy_identifier, PhabricatorObjectHandle $handle = null)
 {
     $is_global = PhabricatorPolicyQuery::isGlobalPolicy($policy_identifier);
     if ($is_global) {
         return PhabricatorPolicyQuery::getGlobalPolicy($policy_identifier);
     }
     $policy = PhabricatorPolicyQuery::getObjectPolicy($policy_identifier);
     if ($policy) {
         return $policy;
     }
     if (!$handle) {
         throw new Exception(pht("Policy identifier is an object PHID ('%s'), but no object handle " . "was provided. A handle must be provided for object policies.", $policy_identifier));
     }
     $handle_phid = $handle->getPHID();
     if ($policy_identifier != $handle_phid) {
         throw new Exception(pht("Policy identifier is an object PHID ('%s'), but the provided " . "handle has a different PHID ('%s'). The handle must correspond " . "to the policy identifier.", $policy_identifier, $handle_phid));
     }
     $policy = id(new PhabricatorPolicy())->setPHID($policy_identifier)->setHref($handle->getURI());
     $phid_type = phid_get_type($policy_identifier);
     switch ($phid_type) {
         case PhabricatorProjectProjectPHIDType::TYPECONST:
             $policy->setType(PhabricatorPolicyType::TYPE_PROJECT);
             $policy->setName($handle->getName());
             break;
         case PhabricatorPeopleUserPHIDType::TYPECONST:
             $policy->setType(PhabricatorPolicyType::TYPE_USER);
             $policy->setName($handle->getFullName());
             break;
         case PhabricatorPolicyPHIDTypePolicy::TYPECONST:
             // TODO: This creates a weird handle-based version of a rule policy.
             // It behaves correctly, but can't be applied since it doesn't have
             // any rules. It is used to render transactions, and might need some
             // cleanup.
             break;
         default:
             $policy->setType(PhabricatorPolicyType::TYPE_MASKED);
             $policy->setName($handle->getFullName());
             break;
     }
     $policy->makeEphemeral();
     return $policy;
 }
 private function performMerge(ManiphestTask $task, PhabricatorObjectHandle $handle, array $phids)
 {
     $user = $this->getRequest()->getUser();
     $response = id(new AphrontReloadResponse())->setURI($handle->getURI());
     $phids = array_fill_keys($phids, true);
     unset($phids[$task->getPHID()]);
     // Prevent merging a task into itself.
     if (!$phids) {
         return $response;
     }
     $targets = id(new ManiphestTask())->loadAllWhere('phid in (%Ls) ORDER BY id ASC', array_keys($phids));
     if (empty($targets)) {
         return $response;
     }
     $editor = new ManiphestTransactionEditor();
     $task_names = array();
     $merge_into_name = 'T' . $task->getID();
     $cc_vector = array();
     $cc_vector[] = $task->getCCPHIDs();
     foreach ($targets as $target) {
         $cc_vector[] = $target->getCCPHIDs();
         $cc_vector[] = array($target->getAuthorPHID(), $target->getOwnerPHID());
         $close_task = id(new ManiphestTransaction())->setAuthorPHID($user->getPHID())->setTransactionType(ManiphestTransactionType::TYPE_STATUS)->setNewValue(ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE)->setComments("✘ Merged into {$merge_into_name}.");
         $editor->applyTransactions($target, array($close_task));
         $task_names[] = 'T' . $target->getID();
     }
     $all_ccs = array_mergev($cc_vector);
     $all_ccs = array_filter($all_ccs);
     $all_ccs = array_unique($all_ccs);
     $task_names = implode(', ', $task_names);
     $add_ccs = id(new ManiphestTransaction())->setAuthorPHID($user->getPHID())->setTransactionType(ManiphestTransactionType::TYPE_CCS)->setNewValue($all_ccs)->setComments("◀ Merged tasks: {$task_names}.");
     $editor->applyTransactions($task, array($add_ccs));
     return $response;
 }
 private function renderBreadcrumbs($slug)
 {
     $ancestor_handles = array();
     $ancestral_slugs = PhrictionDocument::getSlugAncestry($slug);
     $ancestral_slugs[] = $slug;
     if ($ancestral_slugs) {
         $empty_slugs = array_fill_keys($ancestral_slugs, null);
         $ancestors = id(new PhrictionDocument())->loadAllWhere('slug IN (%Ls)', $ancestral_slugs);
         $ancestors = mpull($ancestors, null, 'getSlug');
         $ancestor_phids = mpull($ancestors, 'getPHID');
         $handles = array();
         if ($ancestor_phids) {
             $handles = id(new PhabricatorObjectHandleData($ancestor_phids))->loadHandles();
         }
         $ancestor_handles = array();
         foreach ($ancestral_slugs as $slug) {
             if (isset($ancestors[$slug])) {
                 $ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()];
             } else {
                 $handle = new PhabricatorObjectHandle();
                 $handle->setName(PhrictionDocument::getDefaultSlugTitle($slug));
                 $handle->setURI(PhrictionDocument::getSlugURI($slug));
                 $ancestor_handles[] = $handle;
             }
         }
     }
     $breadcrumbs = array();
     foreach ($ancestor_handles as $ancestor_handle) {
         $breadcrumbs[] = $ancestor_handle->renderLink();
     }
     $list = phutil_render_tag('a', array('href' => '/phriction/'), 'Document Index');
     return '<div class="phriction-breadcrumbs">' . $list . ' &middot; ' . '<span class="phriction-document-crumbs">' . implode(" » ", $breadcrumbs) . '</span>' . '</div>';
 }
 public function addButton(PhabricatorObjectHandle $handle, $button)
 {
     $this->buttons[$handle->getPHID()][] = $button;
     return $this;
 }
 protected function getDefaultPrivateReplyHandlerEmailAddress(PhabricatorObjectHandle $handle, $prefix)
 {
     if ($handle->getType() != PhabricatorPHIDConstants::PHID_TYPE_USER) {
         // You must be a real user to get a private reply handler address.
         return null;
     }
     $receiver = $this->getMailReceiver();
     $receiver_id = $receiver->getID();
     $user_id = $handle->getAlternateID();
     $hash = PhabricatorMetaMTAReceivedMail::computeMailHash($receiver->getMailKey(), $handle->getPHID());
     $domain = $this->getReplyHandlerDomain();
     $address = "{$prefix}{$receiver_id}+{$user_id}+{$hash}@{$domain}";
     return $this->getSingleReplyHandlerPrefix($address);
 }
 private function buildObjectSection(PhabricatorPolicyInterface $object, PhabricatorPolicy $policy, $capability, PhabricatorObjectHandle $handle)
 {
     $viewer = $this->getViewer();
     $capability_name = $this->getCapabilityName($capability);
     $object_section = id(new PHUIPolicySectionView())->setViewer($viewer)->setIcon($handle->getIcon() . ' bluegrey')->setHeader(pht('Object Policy'))->appendList(array(array(phutil_tag('strong', array(), pht('%s:', $capability_name)), ' ', $policy->getShortName())))->appendParagraph(pht('In detail, this means that these users can take this action, ' . 'provided they pass all of the checks described above first:'))->appendList(array(PhabricatorPolicy::getPolicyExplanation($viewer, $policy->getPHID())));
     $strength = $this->getStrengthInformation($object, $policy, $capability);
     if ($strength) {
         $object_section->appendHint($strength);
     }
     return $object_section;
 }
 private function renderMailBody(PhabricatorAuditComment $comment, $cname, PhabricatorObjectHandle $handle, PhabricatorMailReplyHandler $reply_handler, array $inline_comments)
 {
     assert_instances_of($inline_comments, 'PhabricatorInlineCommentInterface');
     $commit = $this->commit;
     $user = $this->user;
     $name = $user->getUsername();
     $verb = PhabricatorAuditActionConstants::getActionPastTenseVerb($comment->getAction());
     $body = array();
     $body[] = "{$name} {$verb} commit {$cname}.";
     if ($comment->getContent()) {
         $body[] = $comment->getContent();
     }
     if ($inline_comments) {
         $block = array();
         $path_map = id(new DiffusionPathQuery())->withPathIDs(mpull($inline_comments, 'getPathID'))->execute();
         $path_map = ipull($path_map, 'path', 'id');
         foreach ($inline_comments as $inline) {
             $path = idx($path_map, $inline->getPathID());
             if ($path === null) {
                 continue;
             }
             $start = $inline->getLineNumber();
             $len = $inline->getLineLength();
             if ($len) {
                 $range = $start . '-' . ($start + $len);
             } else {
                 $range = $start;
             }
             $content = $inline->getContent();
             $block[] = "{$path}:{$range} {$content}";
         }
         $body[] = "INLINE COMMENTS\n  " . implode("\n  ", $block);
     }
     $body[] = "COMMIT\n  " . PhabricatorEnv::getProductionURI($handle->getURI());
     $reply_instructions = $reply_handler->getReplyHandlerInstructions();
     if ($reply_instructions) {
         $body[] = "REPLY HANDLER ACTIONS\n  " . $reply_instructions;
     }
     return implode("\n\n", $body) . "\n";
 }
 private function buildCommitView(PhabricatorObjectHandle $handle = null)
 {
     $request = $this->getRequest();
     $query = new PhabricatorAuditCommitQuery();
     $query->needCommitData(true);
     $use_pager = $this->filter != 'active';
     if ($use_pager) {
         $pager = new AphrontPagerView();
         $pager->setURI($request->getRequestURI(), 'offset');
         $pager->setOffset($request->getInt('offset'));
         $query->setOffset($pager->getOffset());
         $query->setLimit($pager->getPageSize() + 1);
     }
     switch ($this->filter) {
         case 'active':
         case 'author':
             $query->withAuthorPHIDs(array($handle->getPHID()));
             break;
         case 'packagecommits':
             $query->withPackagePHIDs(array($handle->getPHID()));
             break;
     }
     switch ($this->filter) {
         case 'active':
             $query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
             break;
         case 'author':
         case 'packagecommits':
             switch ($this->filterStatus) {
                 case 'open':
                     $query->withStatus(PhabricatorAuditQuery::STATUS_OPEN);
                     break;
             }
             break;
     }
     if ($handle) {
         $handle_name = phutil_escape_html($handle->getName());
     } else {
         $handle_name = null;
     }
     switch ($this->filter) {
         case 'active':
             $header = 'Problem Commits';
             $nodata = 'None of your commits have open concerns.';
             break;
         case 'author':
             $header = "Commits by {$handle_name}";
             $nodata = "No matching commits by {$handle_name}.";
             break;
         case 'commits':
             $header = "Commits";
             $nodata = "No matching commits.";
             break;
         case 'packagecommits':
             $header = "Commits in Package '{$handle_name}'";
             $nodata = "No matching commits in package '{$handle_name}'.";
             break;
     }
     $commits = $query->execute();
     if ($use_pager) {
         $commits = $pager->sliceResults($commits);
     }
     $view = new PhabricatorAuditCommitListView();
     $view->setUser($request->getUser());
     $view->setCommits($commits);
     $view->setNoDataString($nodata);
     $phids = $view->getRequiredHandlePHIDs();
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
     $view->setHandles($handles);
     $panel = new AphrontPanelView();
     $panel->setHeader($header);
     $panel->appendChild($view);
     if ($use_pager) {
         $panel->appendChild($pager);
     }
     return $panel;
 }
Esempio n. 22
0
 private function renderHandleIcon(PhabricatorObjectHandle $handle, $label)
 {
     Javelin::initBehavior('phabricator-tooltips');
     $options = array('class' => 'phui-object-item-handle-icon', 'style' => 'background-image: url(' . $handle->getImageURI() . ')');
     if (strlen($label)) {
         $options['sigil'] = 'has-tooltip';
         $options['meta'] = array('tip' => $label);
     }
     return javelin_tag('span', $options, '');
 }
 protected function renderObjectTagForMail($text, $href, PhabricatorObjectHandle $handle)
 {
     $status_closed = PhabricatorObjectHandle::STATUS_CLOSED;
     $strikethrough = $handle->getStatus() == $status_closed ? 'text-decoration: line-through;' : 'text-decoration: none;';
     return phutil_tag('a', array('href' => $href, 'style' => 'background-color: #e7e7e7;
       border-color: #e7e7e7;
       border-radius: 3px;
       padding: 0 4px;
       font-weight: bold;
       color: black;' . $strikethrough), $text);
 }
 public function loadHandles()
 {
     $types = phid_group_by_type($this->phids);
     $handles = array();
     $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
     foreach ($types as $type => $phids) {
         switch ($type) {
             case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
                 // Black magic!
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     switch ($phid) {
                         case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
                             $handle->setName('Up For Grabs');
                             $handle->setFullName('upforgrabs (Up For Grabs)');
                             $handle->setComplete(true);
                             break;
                         case ManiphestTaskOwner::PROJECT_NO_PROJECT:
                             $handle->setName('No Project');
                             $handle->setFullName('noproject (No Project)');
                             $handle->setComplete(true);
                             break;
                         default:
                             $handle->setName('Foul Magicks');
                             break;
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_USER:
                 $object = new PhabricatorUser();
                 $users = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $users = mpull($users, null, 'getPHID');
                 $image_phids = mpull($users, 'getProfileImagePHID');
                 $image_phids = array_unique(array_filter($image_phids));
                 $images = array();
                 if ($image_phids) {
                     $images = id(new PhabricatorFile())->loadAllWhere('phid IN (%Ls)', $image_phids);
                     $images = mpull($images, 'getBestURI', 'getPHID');
                 }
                 $statuses = id(new PhabricatorUserStatus())->loadCurrentStatuses($phids);
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($users[$phid])) {
                         $handle->setName('Unknown User');
                     } else {
                         $user = $users[$phid];
                         $handle->setName($user->getUsername());
                         $handle->setURI('/p/' . $user->getUsername() . '/');
                         $handle->setFullName($user->getUsername() . ' (' . $user->getRealName() . ')');
                         $handle->setAlternateID($user->getID());
                         $handle->setComplete(true);
                         if (isset($statuses[$phid])) {
                             $handle->setStatus($statuses[$phid]->getTextStatus());
                         }
                         $handle->setDisabled($user->getIsDisabled());
                         $img_uri = idx($images, $user->getProfileImagePHID());
                         if ($img_uri) {
                             $handle->setImageURI($img_uri);
                         } else {
                             $handle->setImageURI(PhabricatorUser::getDefaultProfileImageURI());
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_MLST:
                 $object = new PhabricatorMetaMTAMailingList();
                 $lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $lists = mpull($lists, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($lists[$phid])) {
                         $handle->setName('Unknown Mailing List');
                     } else {
                         $list = $lists[$phid];
                         $handle->setName($list->getName());
                         $handle->setURI($list->getURI());
                         $handle->setFullName($list->getName());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_DREV:
                 $object = new DifferentialRevision();
                 $revs = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $revs = mpull($revs, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($revs[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $rev = $revs[$phid];
                         $handle->setName($rev->getTitle());
                         $handle->setURI('/D' . $rev->getID());
                         $handle->setFullName('D' . $rev->getID() . ': ' . $rev->getTitle());
                         $handle->setComplete(true);
                         $status = $rev->getStatus();
                         if ($status == ArcanistDifferentialRevisionStatus::CLOSED || $status == ArcanistDifferentialRevisionStatus::ABANDONED) {
                             $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
                             $handle->setStatus($closed);
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
                 $object = new PhabricatorRepositoryCommit();
                 $commits = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $commits = mpull($commits, null, 'getPHID');
                 $repository_ids = array();
                 $callsigns = array();
                 if ($commits) {
                     $repository_ids = mpull($commits, 'getRepositoryID');
                     $repositories = id(new PhabricatorRepository())->loadAllWhere('id in (%Ld)', array_unique($repository_ids));
                     $callsigns = mpull($repositories, 'getCallsign');
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($commits[$phid]) || !isset($callsigns[$repository_ids[$phid]])) {
                         $handle->setName('Unknown Commit');
                     } else {
                         $commit = $commits[$phid];
                         $callsign = $callsigns[$repository_ids[$phid]];
                         $repository = $repositories[$repository_ids[$phid]];
                         $commit_identifier = $commit->getCommitIdentifier();
                         // In case where the repository for the commit was deleted,
                         // we don't have have info about the repository anymore.
                         if ($repository) {
                             $name = $repository->formatCommitName($commit_identifier);
                             $handle->setName($name);
                         } else {
                             $handle->setName('Commit ' . 'r' . $callsign . $commit_identifier);
                         }
                         $handle->setURI('/r' . $callsign . $commit_identifier);
                         $handle->setFullName('r' . $callsign . $commit_identifier);
                         $handle->setTimestamp($commit->getEpoch());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_TASK:
                 $object = new ManiphestTask();
                 $tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $tasks = mpull($tasks, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($tasks[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $task = $tasks[$phid];
                         $handle->setName($task->getTitle());
                         $handle->setURI('/T' . $task->getID());
                         $handle->setFullName('T' . $task->getID() . ': ' . $task->getTitle());
                         $handle->setComplete(true);
                         $handle->setAlternateID($task->getID());
                         if ($task->getStatus() != ManiphestTaskStatus::STATUS_OPEN) {
                             $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
                             $handle->setStatus($closed);
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_FILE:
                 $object = new PhabricatorFile();
                 $files = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $files = mpull($files, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($files[$phid])) {
                         $handle->setName('Unknown File');
                     } else {
                         $file = $files[$phid];
                         $handle->setName($file->getName());
                         $handle->setURI($file->getBestURI());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
                 $object = new PhabricatorProject();
                 $projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setURI('/project/view/' . $project->getID() . '/');
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_REPO:
                 $object = new PhabricatorRepository();
                 $repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $repositories = mpull($repositories, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($repositories[$phid])) {
                         $handle->setName('Unknown Repository');
                     } else {
                         $repository = $repositories[$phid];
                         $handle->setName($repository->getCallsign());
                         $handle->setURI('/diffusion/' . $repository->getCallsign() . '/');
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
                 $object = new PhabricatorOwnersPackage();
                 $packages = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $packages = mpull($packages, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($packages[$phid])) {
                         $handle->setName('Unknown Package');
                     } else {
                         $package = $packages[$phid];
                         $handle->setName($package->getName());
                         $handle->setURI('/owners/package/' . $package->getID() . '/');
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
                 $project_dao = new PhabricatorRepositoryArcanistProject();
                 $projects = $project_dao->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Arcanist Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
                 $document_dao = new PhrictionDocument();
                 $content_dao = new PhrictionContent();
                 $conn = $document_dao->establishConnection('r');
                 $documents = queryfx_all($conn, 'SELECT * FROM %T document JOIN %T content
           ON document.contentID = content.id
           WHERE document.phid IN (%Ls)', $document_dao->getTableName(), $content_dao->getTableName(), $phids);
                 $documents = ipull($documents, null, 'phid');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($documents[$phid])) {
                         $handle->setName('Unknown Document');
                     } else {
                         $info = $documents[$phid];
                         $handle->setName($info['title']);
                         $handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             default:
                 $loader = null;
                 if (isset($external_loaders[$type])) {
                     $loader = $external_loaders[$type];
                 } else {
                     if (isset($external_loaders['*'])) {
                         $loader = $external_loaders['*'];
                     }
                 }
                 if ($loader) {
                     $object = newv($loader, array());
                     $handles += $object->loadHandles($phids);
                     break;
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setType($type);
                     $handle->setPHID($phid);
                     $handle->setName('Unknown Object');
                     $handle->setFullName('An Unknown Object');
                     $handles[$phid] = $handle;
                 }
                 break;
         }
     }
     return $handles;
 }
Esempio n. 25
0
 protected function buildHandleInformationDictionary(PhabricatorObjectHandle $handle)
 {
     return array('phid' => $handle->getPHID(), 'uri' => PhabricatorEnv::getProductionURI($handle->getURI()), 'typeName' => $handle->getTypeName(), 'type' => $handle->getType(), 'name' => $handle->getName(), 'fullName' => $handle->getFullName(), 'status' => $handle->getStatus());
 }
 protected function getDefaultPrivateReplyHandlerEmailAddress(PhabricatorObjectHandle $handle, $prefix)
 {
     if ($handle->getType() != PhabricatorPeopleUserPHIDType::TYPECONST) {
         // You must be a real user to get a private reply handler address.
         return null;
     }
     $user = id(new PhabricatorPeopleQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs(array($handle->getPHID()))->executeOne();
     if (!$user) {
         // This may happen if a user was subscribed to something, and was then
         // deleted.
         return null;
     }
     $receiver = $this->getMailReceiver();
     $receiver_id = $receiver->getID();
     $user_id = $user->getID();
     $hash = PhabricatorObjectMailReceiver::computeMailHash($receiver->getMailKey(), $handle->getPHID());
     $domain = $this->getReplyHandlerDomain();
     $address = "{$prefix}{$receiver_id}+{$user_id}+{$hash}@{$domain}";
     return $this->getSingleReplyHandlerPrefix($address);
 }
 public function loadHandles()
 {
     $types = array();
     foreach ($this->phids as $phid) {
         $type = $this->lookupType($phid);
         $types[$type][] = $phid;
     }
     $handles = array();
     $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
     foreach ($types as $type => $phids) {
         switch ($type) {
             case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
                 // Black magic!
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     switch ($phid) {
                         case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
                             $handle->setName('Up For Grabs');
                             $handle->setFullName('upforgrabs (Up For Grabs)');
                             break;
                         default:
                             $handle->setName('Foul Magicks');
                             break;
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_USER:
                 $class = 'PhabricatorUser';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $users = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $users = mpull($users, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($users[$phid])) {
                         $handle->setName('Unknown User');
                     } else {
                         $user = $users[$phid];
                         $handle->setName($user->getUsername());
                         $handle->setURI('/p/' . $user->getUsername() . '/');
                         $handle->setEmail($user->getEmail());
                         $handle->setFullName($user->getUsername() . ' (' . $user->getRealName() . ')');
                         $handle->setAlternateID($user->getID());
                         $img_phid = $user->getProfileImagePHID();
                         if ($img_phid) {
                             $handle->setImageURI(PhabricatorFileURI::getViewURIForPHID($img_phid));
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_MLST:
                 $class = 'PhabricatorMetaMTAMailingList';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $lists = mpull($lists, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($lists[$phid])) {
                         $handle->setName('Unknown Mailing List');
                     } else {
                         $list = $lists[$phid];
                         $handle->setEmail($list->getEmail());
                         $handle->setName($list->getName());
                         $handle->setURI($list->getURI());
                         $handle->setFullName($list->getName());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_DREV:
                 $class = 'DifferentialRevision';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $revs = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $revs = mpull($revs, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($revs[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $rev = $revs[$phid];
                         $handle->setName($rev->getTitle());
                         $handle->setURI('/D' . $rev->getID());
                         $handle->setFullName('D' . $rev->getID() . ': ' . $rev->getTitle());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
                 $class = 'PhabricatorRepositoryCommit';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $commits = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $commits = mpull($commits, null, 'getPHID');
                 $repository_ids = mpull($commits, 'getRepositoryID');
                 $repositories = id(new PhabricatorRepository())->loadAllWhere('id in (%Ld)', array_unique($repository_ids));
                 $callsigns = mpull($repositories, 'getCallsign');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($commits[$phid]) || !isset($callsigns[$repository_ids[$phid]])) {
                         $handle->setName('Unknown Commit');
                     } else {
                         $commit = $commits[$phid];
                         $callsign = $callsigns[$repository_ids[$phid]];
                         $repository = $repositories[$repository_ids[$phid]];
                         $commit_identifier = $commit->getCommitIdentifier();
                         // In case where the repository for the commit was deleted,
                         // we don't have have info about the repository anymore.
                         if ($repository) {
                             $vcs = $repository->getVersionControlSystem();
                             if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
                                 $short_identifier = substr($commit_identifier, 0, 16);
                             } else {
                                 $short_identifier = $commit_identifier;
                             }
                             $handle->setName('r' . $callsign . $short_identifier);
                         } else {
                             $handle->setName('Commit ' . 'r' . $callsign . $commit_identifier);
                         }
                         $handle->setURI('/r' . $callsign . $commit_identifier);
                         $handle->setFullName('r' . $callsign . $commit_identifier);
                         $handle->setTimestamp($commit->getEpoch());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_TASK:
                 $class = 'ManiphestTask';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $tasks = mpull($tasks, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($tasks[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $task = $tasks[$phid];
                         $handle->setName($task->getTitle());
                         $handle->setURI('/T' . $task->getID());
                         $handle->setFullName('T' . $task->getID() . ': ' . $task->getTitle());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_FILE:
                 $class = 'PhabricatorFile';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $files = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $files = mpull($files, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($files[$phid])) {
                         $handle->setName('Unknown File');
                     } else {
                         $file = $files[$phid];
                         $handle->setName($file->getName());
                         $handle->setURI($file->getViewURI());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
                 $class = 'PhabricatorProject';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setURI('/project/view/' . $project->getID() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_REPO:
                 $class = 'PhabricatorRepository';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $repositories = mpull($repositories, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($repositories[$phid])) {
                         $handle->setName('Unknown Repository');
                     } else {
                         $repository = $repositories[$phid];
                         $handle->setName($repository->getCallsign());
                         $handle->setURI('/diffusion/' . $repository->getCallsign() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
                 $class = 'PhabricatorOwnersPackage';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $packages = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $packages = mpull($packages, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($packages[$phid])) {
                         $handle->setName('Unknown Package');
                     } else {
                         $package = $packages[$phid];
                         $handle->setName($package->getName());
                         $handle->setURI('/owners/package/' . $package->getID() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
                 $project_dao = newv('PhabricatorRepositoryArcanistProject', array());
                 $projects = $project_dao->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Arcanist Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
                 $document_dao = newv('PhrictionDocument', array());
                 $content_dao = newv('PhrictionContent', array());
                 $conn = $document_dao->establishConnection('r');
                 $documents = queryfx_all($conn, 'SELECT * FROM %T document JOIN %T content
           ON document.contentID = content.id
           WHERE document.phid IN (%Ls)', $document_dao->getTableName(), $content_dao->getTableName(), $phids);
                 $documents = ipull($documents, null, 'phid');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($documents[$phid])) {
                         $handle->setName('Unknown Document');
                     } else {
                         $info = $documents[$phid];
                         $handle->setName($info['title']);
                         $handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             default:
                 $loader = null;
                 if (isset($external_loaders[$type])) {
                     $loader = $external_loaders[$type];
                 } else {
                     if (isset($external_loaders['*'])) {
                         $loader = $external_loaders['*'];
                     }
                 }
                 if ($loader) {
                     PhutilSymbolLoader::loadClass($loader);
                     $object = newv($loader, array());
                     $handles += $object->loadHandles($phids);
                     break;
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setType($type);
                     $handle->setPHID($phid);
                     $handle->setName('Unknown Object');
                     $handle->setFullName('An Unknown Object');
                     $handles[$phid] = $handle;
                 }
                 break;
         }
     }
     return $handles;
 }