private function renderAuditStatusView(array $audit_requests) { assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest'); $viewer = $this->getViewer(); $authority_map = array_fill_keys($this->auditAuthorityPHIDs, true); $view = new PHUIStatusListView(); foreach ($audit_requests as $request) { $code = $request->getAuditStatus(); $item = new PHUIStatusItemView(); $item->setIcon(PhabricatorAuditStatusConstants::getStatusIcon($code), PhabricatorAuditStatusConstants::getStatusColor($code), PhabricatorAuditStatusConstants::getStatusName($code)); $note = array(); foreach ($request->getAuditReasons() as $reason) { $note[] = phutil_tag('div', array(), $reason); } $item->setNote($note); $auditor_phid = $request->getAuditorPHID(); $target = $viewer->renderHandle($auditor_phid); $item->setTarget($target); if (isset($authority_map[$auditor_phid])) { $item->setHighlighted(true); } $view->addItem($item); } return $view; }
public function render() { $user = $this->user; $authority = array_fill_keys($this->authorityPHIDs, true); $rowc = array(); $last = null; $rows = array(); foreach ($this->audits as $audit) { $commit_phid = $audit->getCommitPHID(); if ($last == $commit_phid) { $commit_name = null; $commit_desc = null; } else { $commit_name = $this->getHandle($commit_phid)->renderLink(); $commit_desc = $this->getCommitDescription($commit_phid); $last = $commit_phid; } $reasons = $audit->getAuditReasons(); foreach ($reasons as $key => $reason) { $reasons[$key] = phutil_escape_html($reason); } $reasons = implode('<br />', $reasons); $status_code = $audit->getAuditStatus(); $status = PhabricatorAuditStatusConstants::getStatusName($status_code); $auditor_handle = $this->getHandle($audit->getAuditorPHID()); $rows[] = array($commit_name, phutil_escape_html($commit_desc), $auditor_handle->renderLink(), phutil_escape_html($status), $reasons); $row_class = null; $has_authority = !empty($authority[$audit->getAuditorPHID()]); if ($has_authority) { $commit_author = $this->commits[$commit_phid]->getAuthorPHID(); // You don't have authority over package and project audits on your own // commits. $auditor_is_user = $audit->getAuditorPHID() == $user->getPHID(); $user_is_author = $commit_author == $user->getPHID(); if ($auditor_is_user || !$user_is_author) { $row_class = 'highlighted'; } } $rowc[] = $row_class; } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Description', 'Auditor', 'Status', 'Details')); $table->setColumnClasses(array('pri', $this->showDescriptions ? 'wide' : '', '', '', $this->showDescriptions ? '' : 'wide')); $table->setRowClasses($rowc); $table->setColumnVisibility(array($this->showDescriptions, $this->showDescriptions, true, true, true)); if ($this->noDataString) { $table->setNoDataString($this->noDataString); } return $table->render(); }
public function execute(PhutilArgumentParser $args) { $viewer = $this->getViewer(); $users = $this->loadUsers($args->getArg('users')); $repos = $this->loadRepos($args->getArg('repositories')); $commits = $this->loadCommits($args->getArg('commits')); $ids = $this->parseList($args->getArg('ids')); $status = $args->getArg('status'); if (!$status) { $status = DiffusionCommitQuery::AUDIT_STATUS_OPEN; } $min_date = $this->loadDate($args->getArg('min-commit-date')); $max_date = $this->loadDate($args->getArg('max-commit-date')); if ($min_date && $max_date && $min_date > $max_date) { throw new PhutilArgumentUsageException('Specified max date must come after specified min date.'); } $is_dry_run = $args->getArg('dry-run'); $query = id(new DiffusionCommitQuery())->setViewer($this->getViewer())->needAuditRequests(true); if ($status) { $query->withAuditStatus($status); } $id_map = array(); if ($ids) { $id_map = array_fuse($ids); $query->withAuditIDs($ids); } if ($repos) { $query->withRepositoryIDs(mpull($repos, 'getID')); } $auditor_map = array(); if ($users) { $auditor_map = array_fuse(mpull($users, 'getPHID')); $query->withAuditorPHIDs($auditor_map); } if ($commits) { $query->withPHIDs(mpull($commits, 'getPHID')); } $commits = $query->execute(); $commits = mpull($commits, null, 'getPHID'); $audits = array(); foreach ($commits as $commit) { $commit_audits = $commit->getAudits(); foreach ($commit_audits as $key => $audit) { if ($id_map && empty($id_map[$audit->getID()])) { unset($commit_audits[$key]); continue; } if ($auditor_map && empty($auditor_map[$audit->getAuditorPHID()])) { unset($commit_audits[$key]); continue; } if ($min_date && $commit->getEpoch() < $min_date) { unset($commit_audits[$key]); continue; } if ($max_date && $commit->getEpoch() > $max_date) { unset($commit_audits[$key]); continue; } } $audits[] = $commit_audits; } $audits = array_mergev($audits); $console = PhutilConsole::getConsole(); if (!$audits) { $console->writeErr("%s\n", pht('No audits match the query.')); return 0; } $handles = id(new PhabricatorHandleQuery())->setViewer($this->getViewer())->withPHIDs(mpull($audits, 'getAuditorPHID'))->execute(); foreach ($audits as $audit) { $commit = $commits[$audit->getCommitPHID()]; $console->writeOut("%s\n", sprintf('%10d %-16s %-16s %s: %s', $audit->getID(), $handles[$audit->getAuditorPHID()]->getName(), PhabricatorAuditStatusConstants::getStatusName($audit->getAuditStatus()), $commit->getRepository()->formatCommitName($commit->getCommitIdentifier()), trim($commit->getSummary()))); } if (!$is_dry_run) { $message = pht('Really delete these %d audit(s)? They will be permanently deleted ' . 'and can not be recovered.', count($audits)); if ($console->confirm($message)) { foreach ($audits as $audit) { $id = $audit->getID(); $console->writeOut("%s\n", pht('Deleting audit %d...', $id)); $audit->delete(); } } } return 0; }
public function buildList() { $user = $this->getUser(); if (!$user) { throw new Exception(pht('You must %s before %s!', 'setUser()', __FUNCTION__ . '()')); } $rowc = array(); $list = new PHUIObjectItemListView(); foreach ($this->commits as $commit) { $commit_phid = $commit->getPHID(); $commit_handle = $this->getHandle($commit_phid); $committed = null; $commit_name = $commit_handle->getName(); $commit_link = $commit_handle->getURI(); $commit_desc = $this->getCommitDescription($commit_phid); $committed = phabricator_datetime($commit->getEpoch(), $user); $audits = mpull($commit->getAudits(), null, 'getAuditorPHID'); $auditors = array(); $reasons = array(); foreach ($audits as $audit) { $auditor_phid = $audit->getAuditorPHID(); $auditors[$auditor_phid] = $this->getHandle($auditor_phid)->renderLink(); } $auditors = phutil_implode_html(', ', $auditors); $authority_audits = array_select_keys($audits, $this->authorityPHIDs); if ($authority_audits) { $audit = reset($authority_audits); } else { $audit = reset($audits); } if ($audit) { $reasons = $audit->getAuditReasons(); $reasons = phutil_implode_html(', ', $reasons); $status_code = $audit->getAuditStatus(); $status_text = PhabricatorAuditStatusConstants::getStatusName($status_code); $status_color = PhabricatorAuditStatusConstants::getStatusColor($status_code); $status_icon = PhabricatorAuditStatusConstants::getStatusIcon($status_code); } else { $reasons = null; $status_text = null; $status_color = null; $status_icon = null; } $author_phid = $commit->getAuthorPHID(); if ($author_phid) { $author_name = $this->getHandle($author_phid)->renderLink(); } else { $author_name = $commit->getCommitData()->getAuthorName(); } $item = id(new PHUIObjectItemView())->setObjectName($commit_name)->setHeader($commit_desc)->setHref($commit_link)->addAttribute(pht('Author: %s', $author_name))->addAttribute($reasons)->addIcon('none', $committed); if (!empty($auditors)) { $item->addByLine(pht('Auditors: %s', $auditors)); } if ($status_color) { $item->setStatusIcon($status_icon . ' ' . $status_color, $status_text); } $list->addItem($item); } if ($this->noDataString) { $list->setNoDataString($this->noDataString); } return $list; }
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { $where = array(); if ($this->repositoryPHIDs !== null) { $map_repositories = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->withPHIDs($this->repositoryPHIDs)->execute(); if (!$map_repositories) { throw new PhabricatorEmptyQueryException(); } $repository_ids = mpull($map_repositories, 'getID'); if ($this->repositoryIDs !== null) { $repository_ids = array_merge($repository_ids, $this->repositoryIDs); } $this->withRepositoryIDs($repository_ids); } if ($this->ids !== null) { $where[] = qsprintf($conn_r, 'commit.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn_r, 'commit.phid IN (%Ls)', $this->phids); } if ($this->repositoryIDs !== null) { $where[] = qsprintf($conn_r, 'commit.repositoryID IN (%Ld)', $this->repositoryIDs); } if ($this->authorPHIDs !== null) { $where[] = qsprintf($conn_r, 'commit.authorPHID IN (%Ls)', $this->authorPHIDs); } if ($this->epochMin !== null) { $where[] = qsprintf($conn_r, 'commit.epoch >= %d', $this->epochMin); } if ($this->epochMax !== null) { $where[] = qsprintf($conn_r, 'commit.epoch <= %d', $this->epochMax); } if ($this->importing !== null) { if ($this->importing) { $where[] = qsprintf($conn_r, '(commit.importStatus & %d) != %d', PhabricatorRepositoryCommit::IMPORTED_ALL, PhabricatorRepositoryCommit::IMPORTED_ALL); } else { $where[] = qsprintf($conn_r, '(commit.importStatus & %d) = %d', PhabricatorRepositoryCommit::IMPORTED_ALL, PhabricatorRepositoryCommit::IMPORTED_ALL); } } if ($this->identifiers !== null) { $min_unqualified = PhabricatorRepository::MINIMUM_UNQUALIFIED_HASH; $min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH; $refs = array(); $bare = array(); foreach ($this->identifiers as $identifier) { $matches = null; preg_match('/^(?:[rR]([A-Z]+:?|[0-9]+:))?(.*)$/', $identifier, $matches); $repo = nonempty(rtrim($matches[1], ':'), null); $commit_identifier = nonempty($matches[2], null); if ($repo === null) { if ($this->defaultRepository) { $repo = $this->defaultRepository->getCallsign(); } } if ($repo === null) { if (strlen($commit_identifier) < $min_unqualified) { continue; } $bare[] = $commit_identifier; } else { $refs[] = array('callsign' => $repo, 'identifier' => $commit_identifier); } } $sql = array(); foreach ($bare as $identifier) { $sql[] = qsprintf($conn_r, '(commit.commitIdentifier LIKE %> AND ' . 'LENGTH(commit.commitIdentifier) = 40)', $identifier); } if ($refs) { $callsigns = ipull($refs, 'callsign'); $repos = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->withIdentifiers($callsigns); $repos->execute(); $repos = $repos->getIdentifierMap(); foreach ($refs as $key => $ref) { $repo = idx($repos, $ref['callsign']); if (!$repo) { continue; } if ($repo->isSVN()) { if (!ctype_digit($ref['identifier'])) { continue; } $sql[] = qsprintf($conn_r, '(commit.repositoryID = %d AND commit.commitIdentifier = %s)', $repo->getID(), (int) $ref['identifier']); } else { if (strlen($ref['identifier']) < $min_qualified) { continue; } $sql[] = qsprintf($conn_r, '(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)', $repo->getID(), $ref['identifier']); } } } if (!$sql) { // If we discarded all possible identifiers (e.g., they all referenced // bogus repositories or were all too short), make sure the query finds // nothing. throw new PhabricatorEmptyQueryException(pht('No commit identifiers.')); } $where[] = '(' . implode(' OR ', $sql) . ')'; } if ($this->auditIDs !== null) { $where[] = qsprintf($conn_r, 'audit.id IN (%Ld)', $this->auditIDs); } if ($this->auditorPHIDs !== null) { $where[] = qsprintf($conn_r, 'audit.auditorPHID IN (%Ls)', $this->auditorPHIDs); } if ($this->auditAwaitingUser) { $awaiting_user_phid = $this->auditAwaitingUser->getPHID(); // Exclude package and project audits associated with commits where // the user is the author. $where[] = qsprintf($conn_r, '(commit.authorPHID IS NULL OR commit.authorPHID != %s) OR (audit.auditorPHID = %s)', $awaiting_user_phid, $awaiting_user_phid); } $status = $this->auditStatus; if ($status !== null) { switch ($status) { case self::AUDIT_STATUS_PARTIAL: $where[] = qsprintf($conn_r, 'commit.auditStatus = %d', PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED); break; case self::AUDIT_STATUS_ACCEPTED: $where[] = qsprintf($conn_r, 'commit.auditStatus = %d', PhabricatorAuditCommitStatusConstants::FULLY_AUDITED); break; case self::AUDIT_STATUS_CONCERN: $where[] = qsprintf($conn_r, 'audit.auditStatus = %s', PhabricatorAuditStatusConstants::CONCERNED); break; case self::AUDIT_STATUS_OPEN: $where[] = qsprintf($conn_r, 'audit.auditStatus in (%Ls)', PhabricatorAuditStatusConstants::getOpenStatusConstants()); if ($this->auditAwaitingUser) { $where[] = qsprintf($conn_r, 'awaiting.auditStatus IS NULL OR awaiting.auditStatus != %s', PhabricatorAuditStatusConstants::RESIGNED); } break; case self::AUDIT_STATUS_ANY: break; default: $valid = array(self::AUDIT_STATUS_ANY, self::AUDIT_STATUS_OPEN, self::AUDIT_STATUS_CONCERN, self::AUDIT_STATUS_ACCEPTED, self::AUDIT_STATUS_PARTIAL); throw new Exception(pht("Unknown audit status '%s'! Valid statuses are: %s.", $status, implode(', ', $valid))); } } $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); }
public function render() { $rowc = array(); $last = null; $rows = array(); foreach ($this->audits as $audit) { $commit_phid = $audit->getCommitPHID(); $committed = null; if ($last == $commit_phid) { $commit_name = null; $commit_desc = null; } else { $commit_name = $this->getHandle($commit_phid)->renderLink(); $commit_desc = $this->getCommitDescription($commit_phid); $commit = idx($this->commits, $commit_phid); if ($commit && $this->user) { $committed = phabricator_datetime($commit->getEpoch(), $this->user); } $last = $commit_phid; } $reasons = $audit->getAuditReasons(); foreach ($reasons as $key => $reason) { $reasons[$key] = phutil_escape_html($reason); } $reasons = implode('<br />', $reasons); $status_code = $audit->getAuditStatus(); $status = PhabricatorAuditStatusConstants::getStatusName($status_code); $auditor_handle = $this->getHandle($audit->getAuditorPHID()); $rows[] = array($commit_name, phutil_escape_html($commit_desc), $committed, $auditor_handle->renderLink(), phutil_escape_html($status), $reasons); $row_class = null; if (array_key_exists($audit->getID(), $this->getHighlightedAudits())) { $row_class = 'highlighted'; } $rowc[] = $row_class; } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Description', 'Committed', 'Auditor', 'Status', 'Details')); $table->setColumnClasses(array('pri', $this->showDescriptions ? 'wide' : '', '', '', '', $this->showDescriptions ? '' : 'wide')); $table->setRowClasses($rowc); $table->setColumnVisibility(array($this->showDescriptions, $this->showDescriptions, $this->showDescriptions, true, true, true)); if ($this->noDataString) { $table->setNoDataString($this->noDataString); } return $table->render(); }
public function processRequest() { $this->request = $this->getRequest(); $this->user = $this->request->getUser(); $this->commitPHID = $this->request->getStr('c-phid'); $this->packagePHID = $this->request->getStr('p-phid'); $relationship = id(new PhabricatorOwnersPackageCommitRelationship())->loadOneWhere('commitPHID = %s AND packagePHID=%s', $this->commitPHID, $this->packagePHID); if (!$relationship) { return new Aphront404Response(); } $package = id(new PhabricatorOwnersPackage())->loadOneWhere("phid = %s", $this->packagePHID); $owners = id(new PhabricatorOwnersOwner())->loadAllWhere('packageID = %d', $package->getID()); $owners_phids = mpull($owners, 'getUserPHID'); if (!$this->user->getIsAdmin() && !in_array($this->user->getPHID(), $owners_phids)) { return $this->buildStandardPageResponse(id(new AphrontErrorView())->setSeverity(AphrontErrorView::SEVERITY_ERROR)->setTitle("Only admin or owner of the package can audit the " . "commit."), array('title' => 'Audit a Commit')); } if ($this->request->isFormPost()) { return $this->saveAuditComments(); } $package_link = phutil_render_tag('a', array('href' => '/owners/package/' . $package->getID() . '/'), phutil_escape_html($package->getName())); $phids = array($this->commitPHID); $loader = new PhabricatorObjectHandleData($phids); $handles = $loader->loadHandles(); $objects = $loader->loadObjects(); $commit_handle = $handles[$this->commitPHID]; $commit_object = $objects[$this->commitPHID]; $commit_data = $commit_object->getCommitData(); $commit_epoch = $commit_handle->getTimeStamp(); $commit_datetime = phabricator_datetime($commit_epoch, $this->user); $commit_link = $this->renderHandleLink($commit_handle); $revision_author_phid = null; $revision_reviewedby_phid = null; $revision_link = null; $revision_id = $commit_data->getCommitDetail('differential.revisionID'); if ($revision_id) { $revision = id(new DifferentialRevision())->load($revision_id); if ($revision) { $revision->loadRelationships(); $revision_author_phid = $revision->getAuthorPHID(); $revision_reviewedby_phid = $revision->loadReviewedBy(); $revision_link = phutil_render_tag('a', array('href' => '/D' . $revision->getID()), phutil_escape_html($revision->getTitle())); } } $commit_author_phid = $commit_data->getCommitDetail('authorPHID'); $commit_reviewedby_phid = $commit_data->getCommitDetail('reviewerPHID'); $conn_r = id(new PhabricatorAuditComment())->establishConnection('r'); $latest_comment = queryfx_one($conn_r, 'SELECT * FROM %T WHERE targetPHID = %s and actorPHID in (%Ls) ORDER BY ID DESC LIMIT 1', id(new PhabricatorAuditComment())->getTableName(), $this->commitPHID, $owners_phids); $auditor_phid = $latest_comment['actorPHID']; $user_phids = array_unique(array_filter(array($revision_author_phid, $revision_reviewedby_phid, $commit_author_phid, $commit_reviewedby_phid, $auditor_phid))); $user_loader = new PhabricatorObjectHandleData($user_phids); $user_handles = $user_loader->loadHandles(); if ($commit_author_phid && isset($handles[$commit_author_phid])) { $commit_author_link = $handles[$commit_author_phid]->renderLink(); } else { $commit_author_link = phutil_escape_html($commit_data->getAuthorName()); } $reasons = $relationship->getAuditReasons(); $reasons = array_map('phutil_escape_html', $reasons); $reasons = implode($reasons, '<br>'); $latest_comment_content = id(new AphrontFormTextAreaControl())->setLabel('Audit comments')->setName('latest_comments')->setReadOnly(true)->setValue($latest_comment['content']); $latest_comment_epoch = $latest_comment['dateModified']; $latest_comment_datetime = phabricator_datetime($latest_comment_epoch, $this->user); $select = id(new AphrontFormSelectControl())->setLabel('Audit it')->setName('action')->setValue(PhabricatorAuditActionConstants::ACCEPT)->setOptions(PhabricatorAuditActionConstants::getActionNameMap()); $comment = id(new AphrontFormTextAreaControl())->setLabel('Audit comments')->setName('comments')->setCaption("Explain the audit."); $submit = id(new AphrontFormSubmitControl())->setValue('Save')->addCancelButton('/owners/related/view/audit/?phid=' . $this->packagePHID); $form = id(new AphrontFormView())->setUser($this->user)->appendChild(id(new AphrontFormMarkupControl())->setLabel('Package')->setValue($package_link))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Commit')->setValue($commit_link))->appendChild(new AphrontFormDividerControl())->appendChild(id(new AphrontFormStaticControl())->setLabel('Commit Summary')->setValue(phutil_escape_html($commit_data->getSummary())))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Commit Author')->setValue($commit_author_link))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Commit Reviewed By')->setValue($this->renderHandleLink(idx($user_handles, $commit_reviewedby_phid))))->appendChild(id(new AphrontFormStaticControl())->setLabel('Commit Time')->setValue($commit_datetime))->appendChild(new AphrontFormDividerControl())->appendChild(id(new AphrontFormMarkupControl())->setLabel('Revision')->setValue($revision_link))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Revision Author')->setValue($this->renderHandleLink(idx($user_handles, $revision_author_phid))))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Revision Reviewed By')->setValue($this->renderHandleLink(idx($user_handles, $revision_reviewedby_phid))))->appendChild(new AphrontFormDividerControl())->appendChild(id(new AphrontFormMarkupControl())->setLabel('Audit Reasons')->setValue($reasons))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Latest Auditor')->setValue($this->renderHandleLink(idx($user_handles, $auditor_phid))))->appendChild(id(new AphrontFormStaticControl())->setLabel('Latest Audit Status')->setValue(idx(PhabricatorAuditStatusConstants::getStatusNameMap(), $relationship->getAuditStatus())))->appendChild(id(new AphrontFormStaticControl())->setLabel('Latest Audit Time')->setValue($latest_comment_datetime))->appendChild($latest_comment_content)->appendChild(new AphrontFormDividerControl())->appendChild($select)->appendChild($comment)->appendChild($submit); $panel = id(new AphrontPanelView())->setHeader('Audit a Commit')->setWidth(AphrontPanelView::WIDTH_WIDE)->appendChild($form); return $this->buildStandardPageResponse($panel, array('title' => 'Audit a Commit')); }
private function renderCommitTable($data, PhabricatorOwnersPackage $package) { $commit_phids = array_keys($data); $loader = new PhabricatorObjectHandleData($commit_phids); $handles = $loader->loadHandles(); $objects = $loader->loadObjects(); $owners = id(new PhabricatorOwnersOwner())->loadAllWhere('packageID = %d', $package->getID()); $owners_phids = mpull($owners, 'getUserPHID'); if ($this->user->getIsAdmin() || in_array($this->user->getPHID(), $owners_phids)) { $allowed_to_audit = true; } else { $allowed_to_audit = false; } $rows = array(); foreach ($commit_phids as $commit_phid) { $handle = $handles[$commit_phid]; $object = $objects[$commit_phid]; $commit_data = $object->getCommitData(); $epoch = $handle->getTimeStamp(); $date = phabricator_date($epoch, $this->user); $time = phabricator_time($epoch, $this->user); $link = phutil_render_tag('a', array('href' => $handle->getURI()), phutil_escape_html($handle->getName())); $row = array($link, $date, $time, phutil_escape_html($commit_data->getSummary())); if ($this->view === 'audit') { $relationship = $data[$commit_phid]; $status_link = phutil_escape_html(idx(PhabricatorAuditStatusConstants::getStatusNameMap(), $relationship['auditStatus'])); if ($allowed_to_audit) { $status_link = phutil_render_tag('a', array('href' => sprintf('/audit/edit/?c-phid=%s&p-phid=%s', idx($relationship, 'commitPHID'), $this->packagePHID)), $status_link); } $reasons = json_decode($relationship['auditReasons'], true); $reasons = array_map('phutil_escape_html', $reasons); $reasons = implode($reasons, '<br>'); $row = array_merge($row, array($status_link, $reasons)); } $rows[] = $row; } $commit_table = new AphrontTableView($rows); $headers = array('Commit', 'Date', 'Time', 'Summary'); if ($this->view === 'audit') { $headers = array_merge($headers, array('Audit Status', 'Audit Reasons')); } $commit_table->setHeaders($headers); $column_classes = array('', '', 'right', 'wide'); if ($this->view === 'audit') { $column_classes = array_merge($column_classes, array('', '')); } $commit_table->setColumnClasses($column_classes); $list_panel = new AphrontPanelView(); $list_panel->setHeader('Commits Related to package "' . phutil_render_tag('a', array('href' => '/owners/package/' . $package->getID() . '/'), phutil_escape_html($package->getName())) . '"' . ($this->view === 'audit' ? ' and need attention' : '')); $list_panel->appendChild($commit_table); return $list_panel; }
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); if ($this->repositoryPHIDs !== null) { $map_repositories = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->withPHIDs($this->repositoryPHIDs)->execute(); if (!$map_repositories) { throw new PhabricatorEmptyQueryException(); } $repository_ids = mpull($map_repositories, 'getID'); if ($this->repositoryIDs !== null) { $repository_ids = array_merge($repository_ids, $this->repositoryIDs); } $this->withRepositoryIDs($repository_ids); } if ($this->ids !== null) { $where[] = qsprintf($conn, 'commit.id IN (%Ld)', $this->ids); } if ($this->phids !== null) { $where[] = qsprintf($conn, 'commit.phid IN (%Ls)', $this->phids); } if ($this->repositoryIDs !== null) { $where[] = qsprintf($conn, 'commit.repositoryID IN (%Ld)', $this->repositoryIDs); } if ($this->authorPHIDs !== null) { $where[] = qsprintf($conn, 'commit.authorPHID IN (%Ls)', $this->authorPHIDs); } if ($this->epochMin !== null) { $where[] = qsprintf($conn, 'commit.epoch >= %d', $this->epochMin); } if ($this->epochMax !== null) { $where[] = qsprintf($conn, 'commit.epoch <= %d', $this->epochMax); } if ($this->importing !== null) { if ($this->importing) { $where[] = qsprintf($conn, '(commit.importStatus & %d) != %d', PhabricatorRepositoryCommit::IMPORTED_ALL, PhabricatorRepositoryCommit::IMPORTED_ALL); } else { $where[] = qsprintf($conn, '(commit.importStatus & %d) = %d', PhabricatorRepositoryCommit::IMPORTED_ALL, PhabricatorRepositoryCommit::IMPORTED_ALL); } } if ($this->identifiers !== null) { $min_unqualified = PhabricatorRepository::MINIMUM_UNQUALIFIED_HASH; $min_qualified = PhabricatorRepository::MINIMUM_QUALIFIED_HASH; $refs = array(); $bare = array(); foreach ($this->identifiers as $identifier) { $matches = null; preg_match('/^(?:[rR]([A-Z]+:?|[0-9]+:))?(.*)$/', $identifier, $matches); $repo = nonempty(rtrim($matches[1], ':'), null); $commit_identifier = nonempty($matches[2], null); if ($repo === null) { if ($this->defaultRepository) { $repo = $this->defaultRepository->getPHID(); } } if ($repo === null) { if (strlen($commit_identifier) < $min_unqualified) { continue; } $bare[] = $commit_identifier; } else { $refs[] = array('repository' => $repo, 'identifier' => $commit_identifier); } } $sql = array(); foreach ($bare as $identifier) { $sql[] = qsprintf($conn, '(commit.commitIdentifier LIKE %> AND ' . 'LENGTH(commit.commitIdentifier) = 40)', $identifier); } if ($refs) { $repositories = ipull($refs, 'repository'); $repos = id(new PhabricatorRepositoryQuery())->setViewer($this->getViewer())->withIdentifiers($repositories); $repos->execute(); $repos = $repos->getIdentifierMap(); foreach ($refs as $key => $ref) { $repo = idx($repos, $ref['repository']); if (!$repo) { continue; } if ($repo->isSVN()) { if (!ctype_digit((string) $ref['identifier'])) { continue; } $sql[] = qsprintf($conn, '(commit.repositoryID = %d AND commit.commitIdentifier = %s)', $repo->getID(), (int) $ref['identifier']); } else { if (strlen($ref['identifier']) < $min_qualified) { continue; } $identifier = $ref['identifier']; if (strlen($identifier) == 40) { // MySQL seems to do slightly better with this version if the // clause, so issue it if we have a full commit hash. $sql[] = qsprintf($conn, '(commit.repositoryID = %d AND commit.commitIdentifier = %s)', $repo->getID(), $identifier); } else { $sql[] = qsprintf($conn, '(commit.repositoryID = %d AND commit.commitIdentifier LIKE %>)', $repo->getID(), $identifier); } } } } if (!$sql) { // If we discarded all possible identifiers (e.g., they all referenced // bogus repositories or were all too short), make sure the query finds // nothing. throw new PhabricatorEmptyQueryException(pht('No commit identifiers.')); } $where[] = '(' . implode(' OR ', $sql) . ')'; } if ($this->auditIDs !== null) { $where[] = qsprintf($conn, 'audit.id IN (%Ld)', $this->auditIDs); } if ($this->auditorPHIDs !== null) { $where[] = qsprintf($conn, 'audit.auditorPHID IN (%Ls)', $this->auditorPHIDs); } if ($this->needsAuditByPHIDs !== null) { $where[] = qsprintf($conn, 'needs.auditorPHID IN (%Ls)', $this->needsAuditByPHIDs); } $status = $this->auditStatus; if ($status !== null) { switch ($status) { case self::AUDIT_STATUS_PARTIAL: $where[] = qsprintf($conn, 'commit.auditStatus = %d', PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED); break; case self::AUDIT_STATUS_ACCEPTED: $where[] = qsprintf($conn, 'commit.auditStatus = %d', PhabricatorAuditCommitStatusConstants::FULLY_AUDITED); break; case self::AUDIT_STATUS_CONCERN: $where[] = qsprintf($conn, 'status.auditStatus = %s', PhabricatorAuditStatusConstants::CONCERNED); break; case self::AUDIT_STATUS_OPEN: $where[] = qsprintf($conn, 'status.auditStatus in (%Ls)', PhabricatorAuditStatusConstants::getOpenStatusConstants()); break; case self::AUDIT_STATUS_ANY: break; default: $valid = array(self::AUDIT_STATUS_ANY, self::AUDIT_STATUS_OPEN, self::AUDIT_STATUS_CONCERN, self::AUDIT_STATUS_ACCEPTED, self::AUDIT_STATUS_PARTIAL); throw new Exception(pht("Unknown audit status '%s'! Valid statuses are: %s.", $status, implode(', ', $valid))); } } return $where; }
private function buildWhereClause($conn_r) { $where = array(); if ($this->commitPHIDs) { $where[] = qsprintf($conn_r, 'req.commitPHID IN (%Ls)', $this->commitPHIDs); } if ($this->auditorPHIDs) { $where[] = qsprintf($conn_r, 'req.auditorPHID IN (%Ls)', $this->auditorPHIDs); } if ($this->awaitingUser) { // Exclude package and project audits associated with commits where // the user is the author. $where[] = qsprintf($conn_r, '(commit.authorPHID IS NULL OR commit.authorPHID != %s) OR (req.auditorPHID = %s)', $this->awaitingUser->getPHID(), $this->awaitingUser->getPHID()); } $status = $this->status; switch ($status) { case self::STATUS_OPEN: $where[] = qsprintf($conn_r, 'req.auditStatus in (%Ls)', PhabricatorAuditStatusConstants::getOpenStatusConstants()); if ($this->awaitingUser) { $where[] = qsprintf($conn_r, 'awaiting.auditStatus IS NULL OR awaiting.auditStatus != %s', PhabricatorAuditStatusConstants::RESIGNED); } break; case self::STATUS_ANY: break; default: throw new Exception("Unknown status '{$status}'!"); } if ($where) { $where = 'WHERE (' . implode(') AND (', $where) . ')'; } else { $where = ''; } return $where; }