protected function execute(ConduitAPIRequest $request)
 {
     $diff = null;
     $revision_id = $request->getValue('revision_id');
     $revision = id(new DifferentialRevision())->load($revision_id);
     if (!$revision) {
         throw new ConduitException('ERR_BAD_REVISION');
     }
     $revision->loadRelationships();
     $reviewer_phids = array_values($revision->getReviewers());
     $diffs = $revision->loadDiffs();
     $diff_dicts = array();
     foreach ($diffs as $diff) {
         $diff->attachChangesets($diff->loadChangesets());
         // TODO: We could batch this to improve performance.
         foreach ($diff->getChangesets() as $changeset) {
             $changeset->attachHunks($changeset->loadHunks());
         }
         $diff_dicts[] = $diff->getDiffDict();
     }
     $commit_dicts = array();
     $commit_phids = $revision->loadCommitPHIDs();
     $handles = id(new PhabricatorObjectHandleData($commit_phids))->loadHandles();
     foreach ($commit_phids as $commit_phid) {
         $commit_dicts[] = array('fullname' => $handles[$commit_phid]->getFullName(), 'dateCommitted' => $handles[$commit_phid]->getTimestamp());
     }
     $auxiliary_fields = $this->loadAuxiliaryFields($revision);
     $dict = array('id' => $revision->getID(), 'phid' => $revision->getPHID(), 'authorPHID' => $revision->getAuthorPHID(), 'uri' => PhabricatorEnv::getURI('/D' . $revision->getID()), 'title' => $revision->getTitle(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'reviewerPHIDs' => $reviewer_phids, 'diffs' => $diff_dicts, 'commits' => $commit_dicts, 'auxiliary' => $auxiliary_fields);
     return $dict;
 }
 public static function renderFullDescription($status)
 {
     $color = self::getRevisionStatusColor($status);
     $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
     $img = id(new PHUIIconView())->setIconFont(self::getRevisionStatusIcon($status));
     $tag = phutil_tag('span', array('class' => 'phui-header-status phui-header-' . $color), array($img, $status_name));
     return $tag;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $query = $request->getValue('query');
     $guids = $request->getValue('guids');
     $results = array();
     if (!$guids) {
         return $results;
     }
     $revisions = id(new DifferentialRevisionListData($query, (array) $guids))->loadRevisions();
     foreach ($revisions as $revision) {
         $diff = $revision->loadActiveDiff();
         if (!$diff) {
             continue;
         }
         $id = $revision->getID();
         $results[] = array('id' => $id, 'phid' => $revision->getPHID(), 'name' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'authorPHID' => $revision->getAuthorPHID(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'sourcePath' => $diff->getSourcePath());
     }
     return $results;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $diff = null;
     $revision_id = $request->getValue('revision_id');
     $revision = id(new DifferentialRevisionQuery())->withIDs(array($revision_id))->setViewer($request->getUser())->needRelationships(true)->needReviewerStatus(true)->executeOne();
     if (!$revision) {
         throw new ConduitException('ERR_BAD_REVISION');
     }
     $reviewer_phids = array_values($revision->getReviewers());
     $diffs = id(new DifferentialDiffQuery())->setViewer($request->getUser())->withRevisionIDs(array($revision_id))->needChangesets(true)->needArcanistProjects(true)->execute();
     $diff_dicts = mpull($diffs, 'getDiffDict');
     $commit_dicts = array();
     $commit_phids = $revision->loadCommitPHIDs();
     $handles = id(new PhabricatorHandleQuery())->setViewer($request->getUser())->withPHIDs($commit_phids)->execute();
     foreach ($commit_phids as $commit_phid) {
         $commit_dicts[] = array('fullname' => $handles[$commit_phid]->getFullName(), 'dateCommitted' => $handles[$commit_phid]->getTimestamp());
     }
     $field_data = $this->loadCustomFieldsForRevisions($request->getUser(), array($revision));
     $dict = array('id' => $revision->getID(), 'phid' => $revision->getPHID(), 'authorPHID' => $revision->getAuthorPHID(), 'uri' => PhabricatorEnv::getURI('/D' . $revision->getID()), 'title' => $revision->getTitle(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'reviewerPHIDs' => $reviewer_phids, 'diffs' => $diff_dicts, 'commits' => $commit_dicts, 'auxiliary' => idx($field_data, $revision->getPHID(), array()));
     return $dict;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $type = $request->getValue('query');
     $guids = $request->getValue('guids');
     $results = array();
     if (!$guids) {
         return $results;
     }
     $query = id(new DifferentialRevisionQuery())->setViewer($request->getUser());
     switch ($type) {
         case 'open':
             $query->withStatus(DifferentialRevisionQuery::STATUS_OPEN)->withAuthors($guids);
             break;
         case 'committable':
             $query->withStatus(DifferentialRevisionQuery::STATUS_ACCEPTED)->withAuthors($guids);
             break;
         case 'revision-ids':
             $query->withIDs($guids);
             break;
         case 'owned':
             $query->withAuthors($guids);
             break;
         case 'phids':
             $query->withPHIDs($guids);
             break;
     }
     $revisions = $query->execute();
     foreach ($revisions as $revision) {
         $diff = $revision->loadActiveDiff();
         if (!$diff) {
             continue;
         }
         $id = $revision->getID();
         $results[] = array('id' => $id, 'phid' => $revision->getPHID(), 'name' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'authorPHID' => $revision->getAuthorPHID(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'sourcePath' => $diff->getSourcePath());
     }
     return $results;
 }
 public static function renderTagForRevision(DifferentialRevision $revision)
 {
     $status = $revision->getStatus();
     $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
     return id(new PHUITagView())->setType(PHUITagView::TYPE_STATE)->setName($status_name);
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $authors = $request->getValue('authors');
     $ccs = $request->getValue('ccs');
     $reviewers = $request->getValue('reviewers');
     $status = $request->getValue('status');
     $order = $request->getValue('order');
     $path_pairs = $request->getValue('paths');
     $commit_hashes = $request->getValue('commitHashes');
     $limit = $request->getValue('limit');
     $offset = $request->getValue('offset');
     $ids = $request->getValue('ids');
     $phids = $request->getValue('phids');
     $subscribers = $request->getValue('subscribers');
     $responsible_users = $request->getValue('responsibleUsers');
     $branches = $request->getValue('branches');
     $query = id(new DifferentialRevisionQuery())->setViewer($request->getUser());
     if ($authors) {
         $query->withAuthors($authors);
     }
     if ($ccs) {
         $query->withCCs($ccs);
     }
     if ($reviewers) {
         $query->withReviewers($reviewers);
     }
     if ($path_pairs) {
         $paths = array();
         foreach ($path_pairs as $pair) {
             list($callsign, $path) = $pair;
             $paths[] = $path;
         }
         $path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs();
         if (count($path_map) != count($paths)) {
             $unknown_paths = array();
             foreach ($paths as $p) {
                 if (!idx($path_map, $p)) {
                     $unknown_paths[] = $p;
                 }
             }
             throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(pht('Unknown paths: %s', implode(', ', $unknown_paths)));
         }
         $repos = array();
         foreach ($path_pairs as $pair) {
             list($callsign, $path) = $pair;
             if (!idx($repos, $callsign)) {
                 $repos[$callsign] = id(new PhabricatorRepositoryQuery())->setViewer($request->getUser())->withCallsigns(array($callsign))->executeOne();
                 if (!$repos[$callsign]) {
                     throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(pht('Unknown repo callsign: %s', $callsign));
                 }
             }
             $repo = $repos[$callsign];
             $query->withPath($repo->getID(), idx($path_map, $path));
         }
     }
     if ($commit_hashes) {
         $hash_types = ArcanistDifferentialRevisionHash::getTypes();
         foreach ($commit_hashes as $info) {
             list($type, $hash) = $info;
             if (empty($type) || !in_array($type, $hash_types) || empty($hash)) {
                 throw new ConduitException('ERR-INVALID-PARAMETER');
             }
         }
         $query->withCommitHashes($commit_hashes);
     }
     if ($status) {
         $query->withStatus($status);
     }
     if ($order) {
         $query->setOrder($order);
     }
     if ($limit) {
         $query->setLimit($limit);
     }
     if ($offset) {
         $query->setOffset($offset);
     }
     if ($ids) {
         $query->withIDs($ids);
     }
     if ($phids) {
         $query->withPHIDs($phids);
     }
     if ($responsible_users) {
         $query->withResponsibleUsers($responsible_users);
     }
     if ($subscribers) {
         $query->withCCs($subscribers);
     }
     if ($branches) {
         $query->withBranches($branches);
     }
     $query->needRelationships(true);
     $query->needCommitPHIDs(true);
     $query->needDiffIDs(true);
     $query->needActiveDiffs(true);
     $query->needHashes(true);
     $revisions = $query->execute();
     $field_data = $this->loadCustomFieldsForRevisions($request->getUser(), $revisions);
     $results = array();
     foreach ($revisions as $revision) {
         $diff = $revision->getActiveDiff();
         if (!$diff) {
             continue;
         }
         $id = $revision->getID();
         $phid = $revision->getPHID();
         $result = array('id' => $id, 'phid' => $phid, 'title' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'dateModified' => $revision->getDateModified(), 'authorPHID' => $revision->getAuthorPHID(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'properties' => $revision->getProperties(), 'branch' => $diff->getBranch(), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'activeDiffPHID' => $diff->getPHID(), 'diffs' => $revision->getDiffIDs(), 'commits' => $revision->getCommitPHIDs(), 'reviewers' => array_values($revision->getReviewers()), 'ccs' => array_values($revision->getCCPHIDs()), 'hashes' => $revision->getHashes(), 'auxiliary' => idx($field_data, $phid, array()), 'repositoryPHID' => $diff->getRepositoryPHID());
         // TODO: This is a hacky way to put permissions on this field until we
         // have first-class support, see T838.
         if ($revision->getAuthorPHID() == $request->getUser()->getPHID()) {
             $result['sourcePath'] = $diff->getSourcePath();
         }
         $results[] = $result;
     }
     return $results;
 }
 public function renderValueForRevisionList(DifferentialRevision $revision)
 {
     return ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus());
 }
 public static function renderFullDescription($status)
 {
     $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
     $tag = id(new PHUITagView())->setName($status_name)->setIcon(self::getRevisionStatusIcon($status))->setShade(self::getRevisionStatusColor($status))->setType(PHUITagView::TYPE_SHADE);
     return $tag;
 }
 public function render()
 {
     $user = $this->user;
     if (!$user) {
         throw new PhutilInvalidStateException('setUser');
     }
     $fresh = PhabricatorEnv::getEnvConfig('differential.days-fresh');
     if ($fresh) {
         $fresh = PhabricatorCalendarHoliday::getNthBusinessDay(time(), -$fresh);
     }
     $stale = PhabricatorEnv::getEnvConfig('differential.days-stale');
     if ($stale) {
         $stale = PhabricatorCalendarHoliday::getNthBusinessDay(time(), -$stale);
     }
     $this->initBehavior('phabricator-tooltips', array());
     $this->requireResource('aphront-tooltip-css');
     $list = new PHUIObjectItemListView();
     foreach ($this->revisions as $revision) {
         $item = id(new PHUIObjectItemView())->setUser($user);
         $icons = array();
         $phid = $revision->getPHID();
         $flag = $revision->getFlag($user);
         if ($flag) {
             $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor());
             $icons['flag'] = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $flag_class), '');
         }
         if ($revision->getDrafts($user)) {
             $icons['draft'] = true;
         }
         $modified = $revision->getDateModified();
         $status = $revision->getStatus();
         $show_age = ($fresh || $stale) && $this->highlightAge && !$revision->isClosed();
         if ($stale && $modified < $stale) {
             $object_age = PHUIObjectItemView::AGE_OLD;
         } else {
             if ($fresh && $modified < $fresh) {
                 $object_age = PHUIObjectItemView::AGE_STALE;
             } else {
                 $object_age = PHUIObjectItemView::AGE_FRESH;
             }
         }
         $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
         if (isset($icons['flag'])) {
             $item->addHeadIcon($icons['flag']);
         }
         $item->setObjectName('D' . $revision->getID());
         $item->setHeader($revision->getTitle());
         $item->setHref('/D' . $revision->getID());
         if (isset($icons['draft'])) {
             $draft = id(new PHUIIconView())->setIcon('fa-comment yellow')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Unsubmitted Comments')));
             $item->addAttribute($draft);
         }
         /* Most things 'Need Review', so accept it's the default */
         if ($status != ArcanistDifferentialRevisionStatus::NEEDS_REVIEW) {
             $item->addAttribute($status_name);
         }
         // Author
         $author_handle = $this->handles[$revision->getAuthorPHID()];
         $item->addByline(pht('Author: %s', $author_handle->renderLink()));
         $reviewers = array();
         // TODO: As above, this should be based on `getReviewerStatus()`.
         foreach ($revision->getReviewers() as $reviewer) {
             $reviewers[] = $this->handles[$reviewer]->renderLink();
         }
         if (!$reviewers) {
             $reviewers = phutil_tag('em', array(), pht('None'));
         } else {
             $reviewers = phutil_implode_html(', ', $reviewers);
         }
         $item->addAttribute(pht('Reviewers: %s', $reviewers));
         $item->setEpoch($revision->getDateModified(), $object_age);
         switch ($status) {
             case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
                 $item->setStatusIcon('fa-code grey', pht('Needs Review'));
                 break;
             case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
                 $item->setStatusIcon('fa-refresh red', pht('Needs Revision'));
                 break;
             case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
                 $item->setStatusIcon('fa-headphones red', pht('Changes Planned'));
                 break;
             case ArcanistDifferentialRevisionStatus::ACCEPTED:
                 $item->setStatusIcon('fa-check green', pht('Accepted'));
                 break;
             case ArcanistDifferentialRevisionStatus::CLOSED:
                 $item->setDisabled(true);
                 $item->setStatusIcon('fa-check-square-o black', pht('Closed'));
                 break;
             case ArcanistDifferentialRevisionStatus::ABANDONED:
                 $item->setDisabled(true);
                 $item->setStatusIcon('fa-plane black', pht('Abandoned'));
                 break;
         }
         $list->addItem($item);
     }
     $list->setNoDataString($this->noDataString);
     if ($this->header && !$this->noBox) {
         $list->setFlush(true);
         $list = id(new PHUIObjectBoxView())->setObjectList($list);
         if ($this->header instanceof PHUIHeaderView) {
             $list->setHeader($this->header);
         } else {
             $list->setHeaderText($this->header);
         }
     } else {
         $list->setHeader($this->header);
     }
     return $list;
 }
Пример #11
0
                    break;
                case DifferentialAction::ACTION_RECLAIM:
                case DifferentialAction::ACTION_UPDATE:
                    $new_status = ArcanistDifferentialRevisionStatus::NEEDS_REVIEW;
                    break;
            }
        }
        $revisions[$revision_id] = $revision;
        $map[$revision_id] = $new_status;
    }
}
if (!$revisions) {
    echo "Done -- nothing to do.\n";
}
echo "Found " . count($revisions) . " revisions to update:\n\n";
foreach ($revisions as $id => $revision) {
    $old_status = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus());
    $new_status = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($map[$id]);
    echo "    - D{$id}: " . $revision->getTitle() . "\n";
    echo "      Will update: {$old_status} -> {$new_status}\n\n";
}
$ok = phutil_console_confirm('Apply these changes?');
if (!$ok) {
    echo "Aborted.\n";
    exit(1);
}
echo "Saving changes...\n";
foreach ($revisions as $id => $revision) {
    queryfx($revision->establishConnection('r'), 'UPDATE %T SET status = %d WHERE id = %d', $revision->getTableName(), $map[$id], $id);
}
echo "Done.\n";
Пример #12
0
 public function getStatusDisplayName()
 {
     $status = $this->getStatus();
     return ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $authors = $request->getValue('authors');
     $ccs = $request->getValue('ccs');
     $reviewers = $request->getValue('reviewers');
     $status = $request->getValue('status');
     $order = $request->getValue('order');
     $commit_hashes = $request->getValue('commitHashes');
     $limit = $request->getValue('limit');
     $offset = $request->getValue('offset');
     $ids = $request->getValue('ids');
     $phids = $request->getValue('phids');
     $subscribers = $request->getValue('subscribers');
     $responsible_users = $request->getValue('responsibleUsers');
     $branches = $request->getValue('branches');
     $arc_projects = $request->getValue('arcanistProjects');
     $query = new DifferentialRevisionQuery();
     if ($authors) {
         $query->withAuthors($authors);
     }
     if ($ccs) {
         $query->withCCs($ccs);
     }
     if ($reviewers) {
         $query->withReviewers($reviewers);
     }
     /* TODO: Implement.
         $paths     = $request->getValue('paths');
         if ($paths) {
           foreach ($paths as $path) {
     
             // (Lookup the repository IDs.)
     
             $query->withPath($repository_id, $path);
           }
         }
      */
     if ($commit_hashes) {
         $hash_types = ArcanistDifferentialRevisionHash::getTypes();
         foreach ($commit_hashes as $info) {
             list($type, $hash) = $info;
             if (empty($type) || !in_array($type, $hash_types) || empty($hash)) {
                 throw new ConduitException('ERR-INVALID-PARAMETER');
             }
         }
         $query->withCommitHashes($commit_hashes);
     }
     if ($status) {
         $query->withStatus($status);
     }
     if ($order) {
         $query->setOrder($order);
     }
     if ($limit) {
         $query->setLimit($limit);
     }
     if ($offset) {
         $query->setOffset($offset);
     }
     if ($ids) {
         $query->withIDs($ids);
     }
     if ($phids) {
         $query->withPHIDs($phids);
     }
     if ($responsible_users) {
         $query->withResponsibleUsers($responsible_users);
     }
     if ($subscribers) {
         $query->withSubscribers($subscribers);
     }
     if ($branches) {
         $query->withBranches($branches);
     }
     if ($arc_projects) {
         // This is sort of special-cased, but don't make arc do an extra round
         // trip.
         $projects = id(new PhabricatorRepositoryArcanistProject())->loadAllWhere('name in (%Ls)', $arc_projects);
         if (!$projects) {
             return array();
         }
         $query->withArcanistProjectPHIDs(mpull($projects, 'getPHID'));
     }
     $query->needRelationships(true);
     $query->needCommitPHIDs(true);
     $query->needDiffIDs(true);
     $query->needActiveDiffs(true);
     $revisions = $query->execute();
     $results = array();
     foreach ($revisions as $revision) {
         $diff = $revision->getActiveDiff();
         if (!$diff) {
             continue;
         }
         $id = $revision->getID();
         $result = array('id' => $id, 'phid' => $revision->getPHID(), 'title' => $revision->getTitle(), 'uri' => PhabricatorEnv::getProductionURI('/D' . $id), 'dateCreated' => $revision->getDateCreated(), 'dateModified' => $revision->getDateModified(), 'authorPHID' => $revision->getAuthorPHID(), 'status' => $revision->getStatus(), 'statusName' => ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($revision->getStatus()), 'branch' => $diff->getBranch(), 'summary' => $revision->getSummary(), 'testPlan' => $revision->getTestPlan(), 'lineCount' => $revision->getLineCount(), 'diffs' => $revision->getDiffIDs(), 'commits' => $revision->getCommitPHIDs(), 'reviewers' => array_values($revision->getReviewers()), 'ccs' => array_values($revision->getCCPHIDs()));
         // TODO: This is a hacky way to put permissions on this field until we
         // have first-class support, see T838.
         if ($revision->getAuthorPHID() == $request->getUser()->getPHID()) {
             $result['sourcePath'] = $diff->getSourcePath();
         }
         $results[] = $result;
     }
     return $results;
 }
 public function render()
 {
     $viewer = $this->getViewer();
     $this->initBehavior('phabricator-tooltips', array());
     $this->requireResource('aphront-tooltip-css');
     $list = new PHUIObjectItemListView();
     foreach ($this->revisions as $revision) {
         $item = id(new PHUIObjectItemView())->setUser($viewer);
         $icons = array();
         $phid = $revision->getPHID();
         $flag = $revision->getFlag($viewer);
         if ($flag) {
             $flag_class = PhabricatorFlagColor::getCSSClass($flag->getColor());
             $icons['flag'] = phutil_tag('div', array('class' => 'phabricator-flag-icon ' . $flag_class), '');
         }
         if ($revision->getDrafts($viewer)) {
             $icons['draft'] = true;
         }
         $modified = $revision->getDateModified();
         $status = $revision->getStatus();
         $status_name = ArcanistDifferentialRevisionStatus::getNameForRevisionStatus($status);
         if (isset($icons['flag'])) {
             $item->addHeadIcon($icons['flag']);
         }
         $item->setObjectName('D' . $revision->getID());
         $item->setHeader($revision->getTitle());
         $item->setHref('/D' . $revision->getID());
         if (isset($icons['draft'])) {
             $draft = id(new PHUIIconView())->setIcon('fa-comment yellow')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Unsubmitted Comments')));
             $item->addAttribute($draft);
         }
         // Author
         $author_handle = $this->handles[$revision->getAuthorPHID()];
         $item->addByline(pht('Author: %s', $author_handle->renderLink()));
         $unlanded = idx($this->unlandedDependencies, $phid);
         if ($unlanded) {
             $item->addAttribute(array(id(new PHUIIconView())->setIcon('fa-chain-broken', 'red'), ' ', pht('Open Dependencies')));
         }
         $reviewers = array();
         // TODO: As above, this should be based on `getReviewerStatus()`.
         foreach ($revision->getReviewers() as $reviewer) {
             $reviewers[] = $this->handles[$reviewer]->renderLink();
         }
         if (!$reviewers) {
             $reviewers = phutil_tag('em', array(), pht('None'));
         } else {
             $reviewers = phutil_implode_html(', ', $reviewers);
         }
         $item->addAttribute(pht('Reviewers: %s', $reviewers));
         $item->setEpoch($revision->getDateModified());
         switch ($status) {
             case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
                 $item->setStatusIcon('fa-code grey', pht('Needs Review'));
                 break;
             case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
                 $item->setStatusIcon('fa-refresh red', pht('Needs Revision'));
                 break;
             case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
                 $item->setStatusIcon('fa-headphones red', pht('Changes Planned'));
                 break;
             case ArcanistDifferentialRevisionStatus::ACCEPTED:
                 $item->setStatusIcon('fa-check green', pht('Accepted'));
                 break;
             case ArcanistDifferentialRevisionStatus::CLOSED:
                 $item->setDisabled(true);
                 $item->setStatusIcon('fa-check-square-o black', pht('Closed'));
                 break;
             case ArcanistDifferentialRevisionStatus::ABANDONED:
                 $item->setDisabled(true);
                 $item->setStatusIcon('fa-plane black', pht('Abandoned'));
                 break;
         }
         $list->addItem($item);
     }
     $list->setNoDataString($this->noDataString);
     if ($this->header && !$this->noBox) {
         $list->setFlush(true);
         $list = id(new PHUIObjectBoxView())->setBackground($this->background)->setObjectList($list);
         if ($this->header instanceof PHUIHeaderView) {
             $list->setHeader($this->header);
         } else {
             $list->setHeaderText($this->header);
         }
     } else {
         $list->setHeader($this->header);
     }
     return $list;
 }