diff --git a/src/applications/audit/query/PhabricatorCommitSearchEngine.php b/src/applications/audit/query/PhabricatorCommitSearchEngine.php index 7f429dd596..e1c1120608 100644 --- a/src/applications/audit/query/PhabricatorCommitSearchEngine.php +++ b/src/applications/audit/query/PhabricatorCommitSearchEngine.php @@ -1,219 +1,219 @@ needAuditRequests(true) ->needCommitData(true) ->needDrafts(true); } protected function newResultBuckets() { return DiffusionCommitResultBucket::getAllResultBuckets(); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['responsiblePHIDs']) { $query->withResponsiblePHIDs($map['responsiblePHIDs']); } if ($map['auditorPHIDs']) { $query->withAuditorPHIDs($map['auditorPHIDs']); } if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['repositoryPHIDs']) { $query->withRepositoryPHIDs($map['repositoryPHIDs']); } if ($map['packagePHIDs']) { $query->withPackagePHIDs($map['packagePHIDs']); } if ($map['unreachable'] !== null) { $query->withUnreachable($map['unreachable']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Responsible Users')) ->setKey('responsiblePHIDs') ->setConduitKey('responsible') ->setAliases(array('responsible', 'responsibles', 'responsiblePHID')) ->setDatasource(new DifferentialResponsibleDatasource()), id(new PhabricatorUsersSearchField()) ->setLabel(pht('Authors')) ->setKey('authorPHIDs') ->setConduitKey('authors') ->setAliases(array('author', 'authors', 'authorPHID')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Auditors')) ->setKey('auditorPHIDs') ->setConduitKey('auditors') ->setAliases(array('auditor', 'auditors', 'auditorPHID')) ->setDatasource(new DiffusionAuditorFunctionDatasource()), id(new PhabricatorSearchCheckboxesField()) ->setLabel(pht('Audit Status')) ->setKey('statuses') ->setAliases(array('status')) ->setOptions(PhabricatorAuditCommitStatusConstants::getStatusNameMap()), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Repositories')) ->setKey('repositoryPHIDs') ->setConduitKey('repositories') ->setAliases(array('repository', 'repositories', 'repositoryPHID')) ->setDatasource(new DiffusionRepositoryDatasource()), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Packages')) ->setKey('packagePHIDs') ->setConduitKey('packages') ->setAliases(array('package', 'packages', 'packagePHID')) ->setDatasource(new PhabricatorOwnersPackageDatasource()), id(new PhabricatorSearchThreeStateField()) ->setLabel(pht('Unreachable')) ->setKey('unreachable') ->setOptions( pht('(Show All)'), pht('Show Only Unreachable Commits'), pht('Hide Unreachable Commits')) ->setDescription( pht( 'Find or exclude unreachable commits which are not ancestors of '. 'any branch, tag, or ref.')), ); } protected function getURI($path) { return '/diffusion/commit/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['active'] = pht('Active Audits'); $names['authored'] = pht('Authored'); $names['audited'] = pht('Audited'); } $names['all'] = pht('All Commits'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); $viewer_phid = $viewer->getPHID(); switch ($query_key) { case 'all': return $query; case 'active': $bucket_key = DiffusionCommitRequiredActionResultBucket::BUCKETKEY; $open = PhabricatorAuditCommitStatusConstants::getOpenStatusConstants(); $query ->setParameter('responsiblePHIDs', array($viewer_phid)) ->setParameter('statuses', $open) ->setParameter('bucket', $bucket_key) ->setParameter('unreachable', false); return $query; case 'authored': $query ->setParameter('authorPHIDs', array($viewer_phid)); return $query; case 'audited': $query ->setParameter('auditorPHIDs', array($viewer_phid)); return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $commits, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($commits, 'PhabricatorRepositoryCommit'); $viewer = $this->requireViewer(); $bucket = $this->getResultBucket($query); $template = id(new PhabricatorAuditListView()) ->setViewer($viewer) ->setShowDrafts(true); $views = array(); if ($bucket) { $bucket->setViewer($viewer); try { $groups = $bucket->newResultGroups($query, $commits); foreach ($groups as $group) { $views[] = id(clone $template) ->setHeader($group->getName()) ->setNoDataString($group->getNoDataString()) ->setCommits($group->getObjects()); } } catch (Exception $ex) { $this->addError($ex->getMessage()); } } else { $views[] = id(clone $template) ->setCommits($commits) ->setNoDataString(pht('No matching commits.')); } if (count($views) == 1) { $list = head($views)->buildList(); } else { $list = $views; } $result = new PhabricatorApplicationSearchResultView(); $result->setContent($list); return $result; } protected function getNewUserBody() { $view = id(new PHUIBigInfoView()) ->setIcon('fa-check-circle-o') ->setTitle(pht('Welcome to Audit')) ->setDescription( pht('Post-commit code review and auditing. Audits you are assigned '. 'to will appear here.')); return $view; } } diff --git a/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php b/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php index d07ed15d41..e439dd9fb8 100644 --- a/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php +++ b/src/applications/auth/query/PhabricatorAuthInviteSearchEngine.php @@ -1,110 +1,114 @@ pht('All'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $invites, PhabricatorSavedQuery $query) { $phids = array(); foreach ($invites as $invite) { $phids[$invite->getAuthorPHID()] = true; if ($invite->getAcceptedByPHID()) { $phids[$invite->getAcceptedByPHID()] = true; } } return array_keys($phids); } protected function renderResultList( array $invites, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($invites, 'PhabricatorAuthInvite'); $viewer = $this->requireViewer(); $rows = array(); foreach ($invites as $invite) { $rows[] = array( $invite->getEmailAddress(), $handles[$invite->getAuthorPHID()]->renderLink(), ($invite->getAcceptedByPHID() ? $handles[$invite->getAcceptedByPHID()]->renderLink() : null), phabricator_datetime($invite->getDateCreated(), $viewer), ); } $table = id(new AphrontTableView($rows)) ->setHeaders( array( pht('Email Address'), pht('Sent By'), pht('Accepted By'), pht('Invited'), )) ->setColumnClasses( array( '', '', 'wide', 'right', )); $result = new PhabricatorApplicationSearchResultView(); $result->setTable($table); return $result; } } diff --git a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php index fc2bf7ef1e..b57eae5910 100644 --- a/src/applications/badges/query/PhabricatorBadgesSearchEngine.php +++ b/src/applications/badges/query/PhabricatorBadgesSearchEngine.php @@ -1,156 +1,156 @@ setLabel(pht('Name Contains')) ->setKey('name') ->setDescription(pht('Search for badges by name substring.')), id(new PhabricatorSearchCheckboxesField()) ->setKey('qualities') ->setLabel(pht('Quality')) ->setOptions(PhabricatorBadgesQuality::getDropdownQualityMap()), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) ->setOptions( id(new PhabricatorBadgesBadge()) ->getStatusNameMap()), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['qualities']) { $query->withQualities($map['qualities']); } if ($map['name'] !== null) { $query->withNameNgrams($map['name']); } return $query; } protected function getURI($path) { return '/badges/'.$path; } protected function getBuiltinQueryNames() { $names = array(); $names['open'] = pht('Active Badges'); $names['all'] = pht('All Badges'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter( 'statuses', array( PhabricatorBadgesBadge::STATUS_ACTIVE, )); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $badges, PhabricatorSavedQuery $query) { $phids = array(); return $phids; } protected function renderResultList( array $badges, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($badges, 'PhabricatorBadgesBadge'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()); foreach ($badges as $badge) { $quality_name = PhabricatorBadgesQuality::getQualityName( $badge->getQuality()); $mini_badge = id(new PHUIBadgeMiniView()) ->setHeader($badge->getName()) ->setIcon($badge->getIcon()) ->setQuality($badge->getQuality()); $item = id(new PHUIObjectItemView()) ->setHeader($badge->getName()) ->setBadge($mini_badge) ->setHref('/badges/view/'.$badge->getID().'/') ->addAttribute($quality_name) ->addAttribute($badge->getFlavor()); if ($badge->isArchived()) { $item->setDisabled(true); $item->addIcon('fa-ban', pht('Archived')); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No badges found.')); return $result; } protected function getNewUserBody() { $create_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Create a Badge')) ->setHref('/badges/create/') ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Badges let you award and distinguish special users '. 'throughout your instance.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php index 4a65bfd099..032cab0c02 100644 --- a/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarExportSearchEngine.php @@ -1,119 +1,123 @@ requireViewer(); return id(new PhabricatorCalendarExportQuery()) ->withAuthorPHIDs(array($viewer->getPHID())); } protected function buildCustomSearchFields() { return array(); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); return $query; } protected function getURI($path) { return '/calendar/export/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Exports'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $exports, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($exports, 'PhabricatorCalendarExport'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($exports as $export) { $item = id(new PHUIObjectItemView()) ->setViewer($viewer) ->setObjectName(pht('Export %d', $export->getID())) ->setHeader($export->getName()) ->setHref($export->getURI()); if ($export->getIsDisabled()) { $item->setDisabled(true); } $mode = $export->getPolicyMode(); $policy_icon = PhabricatorCalendarExport::getPolicyModeIcon($mode); $policy_name = PhabricatorCalendarExport::getPolicyModeName($mode); $policy_color = PhabricatorCalendarExport::getPolicyModeColor($mode); $item->addIcon( "{$policy_icon} {$policy_color}", $policy_name); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No exports found.')); return $result; } protected function getNewUserBody() { $doc_name = 'Calendar User Guide: Exporting Events'; $doc_href = PhabricatorEnv::getDoclink($doc_name); $create_button = id(new PHUIButtonView()) ->setTag('a') ->setIcon('fa-book white') ->setText($doc_name) ->setHref($doc_href) ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon('fa-download') ->setTitle(pht('No Exports Configured')) ->setDescription( pht( 'You have not set up any events for export from Calendar yet. '. 'See the documentation for instructions on how to get started.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php index 81a1256fca..99f292f9a8 100644 --- a/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarImportLogSearchEngine.php @@ -1,77 +1,81 @@ setLabel(pht('Import Sources')) ->setKey('importSourcePHIDs') ->setAliases(array('importSourcePHID')), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['importSourcePHIDs']) { $query->withImportPHIDs($map['importSourcePHIDs']); } return $query; } protected function getURI($path) { return '/calendar/import/log/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Logs'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $logs, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($logs, 'PhabricatorCalendarImportLog'); $viewer = $this->requireViewer(); $view = id(new PhabricatorCalendarImportLogView()) ->setShowImportSources(true) ->setViewer($viewer) ->setLogs($logs); return id(new PhabricatorApplicationSearchResultView()) ->setTable($view->newTable()); } } diff --git a/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php b/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php index 75252b6dac..a5e44812ea 100644 --- a/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php +++ b/src/applications/calendar/query/PhabricatorCalendarImportSearchEngine.php @@ -1,81 +1,85 @@ newQuery(); return $query; } protected function getURI($path) { return '/calendar/import/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Imports'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $imports, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($imports, 'PhabricatorCalendarImport'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($imports as $import) { $item = id(new PHUIObjectItemView()) ->setViewer($viewer) ->setObjectName(pht('Import %d', $import->getID())) ->setHeader($import->getDisplayName()) ->setHref($import->getURI()); if ($import->getIsDisabled()) { $item->setDisabled(true); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No imports found.')); return $result; } } diff --git a/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php b/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php index 68f7060507..20d034168d 100644 --- a/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php +++ b/src/applications/conduit/query/PhabricatorConduitLogSearchEngine.php @@ -1,204 +1,208 @@ newQuery(); if ($map['callerPHIDs']) { $query->withCallerPHIDs($map['callerPHIDs']); } if ($map['methods']) { $query->withMethods($map['methods']); } if ($map['statuses']) { $query->withMethodStatuses($map['statuses']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setKey('callerPHIDs') ->setLabel(pht('Callers')) ->setAliases(array('caller', 'callers')) ->setDescription(pht('Find calls by specific users.')), id(new PhabricatorSearchStringListField()) ->setKey('methods') ->setLabel(pht('Methods')) ->setDescription(pht('Find calls to specific methods.')), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Method Status')) ->setAliases(array('status')) ->setDescription( pht('Find calls to stable, unstable, or deprecated methods.')) ->setOptions(ConduitAPIMethod::getMethodStatusMap()), ); } protected function getURI($path) { return '/conduit/log/'.$path; } protected function getBuiltinQueryNames() { $names = array(); $viewer = $this->requireViewer(); if ($viewer->isLoggedIn()) { $names['viewer'] = pht('My Calls'); $names['viewerdeprecated'] = pht('My Deprecated Calls'); } $names['all'] = pht('All Call Logs'); $names['deprecated'] = pht('Deprecated Call Logs'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); $viewer_phid = $viewer->getPHID(); $deprecated = array( ConduitAPIMethod::METHOD_STATUS_DEPRECATED, ); switch ($query_key) { case 'viewer': return $query ->setParameter('callerPHIDs', array($viewer_phid)); case 'viewerdeprecated': return $query ->setParameter('callerPHIDs', array($viewer_phid)) ->setParameter('statuses', $deprecated); case 'deprecated': return $query ->setParameter('statuses', $deprecated); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $logs, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($logs, 'PhabricatorConduitMethodCallLog'); $viewer = $this->requireViewer(); $methods = id(new PhabricatorConduitMethodQuery()) ->setViewer($viewer) ->execute(); $methods = mpull($methods, null, 'getAPIMethodName'); Javelin::initBehavior('phabricator-tooltips'); $viewer = $this->requireViewer(); $rows = array(); foreach ($logs as $log) { $caller_phid = $log->getCallerPHID(); if ($caller_phid) { $caller = $viewer->renderHandle($caller_phid); } else { $caller = null; } $method = idx($methods, $log->getMethod()); if ($method) { $method_status = $method->getMethodStatus(); } else { $method_status = null; } switch ($method_status) { case ConduitAPIMethod::METHOD_STATUS_STABLE: $status = null; break; case ConduitAPIMethod::METHOD_STATUS_UNSTABLE: $status = id(new PHUIIconView()) ->setIcon('fa-exclamation-triangle yellow') ->addSigil('has-tooltip') ->setMetadata( array( 'tip' => pht('Unstable'), )); break; case ConduitAPIMethod::METHOD_STATUS_DEPRECATED: $status = id(new PHUIIconView()) ->setIcon('fa-exclamation-triangle red') ->addSigil('has-tooltip') ->setMetadata( array( 'tip' => pht('Deprecated'), )); break; default: $status = id(new PHUIIconView()) ->setIcon('fa-question-circle') ->addSigil('has-tooltip') ->setMetadata( array( 'tip' => pht('Unknown ("%s")', $method_status), )); break; } $rows[] = array( $status, $log->getMethod(), $caller, $log->getError(), pht('%s us', new PhutilNumber($log->getDuration())), phabricator_datetime($log->getDateCreated(), $viewer), ); } $table = id(new AphrontTableView($rows)) ->setHeaders( array( null, pht('Method'), pht('Caller'), pht('Error'), pht('Duration'), pht('Date'), )) ->setColumnClasses( array( null, 'pri', null, 'wide right', null, null, )); return id(new PhabricatorApplicationSearchResultView()) ->setTable($table) ->setNoDataString(pht('No matching calls in log.')); } } diff --git a/src/applications/conduit/query/PhabricatorConduitSearchEngine.php b/src/applications/conduit/query/PhabricatorConduitSearchEngine.php index 787c2154d5..9d244401e6 100644 --- a/src/applications/conduit/query/PhabricatorConduitSearchEngine.php +++ b/src/applications/conduit/query/PhabricatorConduitSearchEngine.php @@ -1,188 +1,192 @@ setParameter('isStable', $request->getStr('isStable')); $saved->setParameter('isUnstable', $request->getStr('isUnstable')); $saved->setParameter('isDeprecated', $request->getStr('isDeprecated')); $saved->setParameter('nameContains', $request->getStr('nameContains')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhabricatorConduitMethodQuery()); $query->withIsStable($saved->getParameter('isStable')); $query->withIsUnstable($saved->getParameter('isUnstable')); $query->withIsDeprecated($saved->getParameter('isDeprecated')); $query->withIsInternal(false); $contains = $saved->getParameter('nameContains'); if (strlen($contains)) { $query->withNameContains($contains); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved) { $form ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Name Contains')) ->setName('nameContains') ->setValue($saved->getParameter('nameContains'))); $is_stable = $saved->getParameter('isStable'); $is_unstable = $saved->getParameter('isUnstable'); $is_deprecated = $saved->getParameter('isDeprecated'); $form ->appendChild( id(new AphrontFormCheckboxControl()) ->setLabel('Stability') ->addCheckbox( 'isStable', 1, hsprintf( '%s: %s', pht('Stable Methods'), pht('Show established API methods with stable interfaces.')), $is_stable) ->addCheckbox( 'isUnstable', 1, hsprintf( '%s: %s', pht('Unstable Methods'), pht('Show new methods which are subject to change.')), $is_unstable) ->addCheckbox( 'isDeprecated', 1, hsprintf( '%s: %s', pht('Deprecated Methods'), pht( 'Show old methods which will be deleted in a future '. 'version of Phabricator.')), $is_deprecated)); } protected function getURI($path) { return '/conduit/'.$path; } protected function getBuiltinQueryNames() { return array( 'modern' => pht('Modern Methods'), 'all' => pht('All Methods'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'modern': return $query ->setParameter('isStable', true) ->setParameter('isUnstable', true); case 'all': return $query ->setParameter('isStable', true) ->setParameter('isUnstable', true) ->setParameter('isDeprecated', true); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $methods, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($methods, 'ConduitAPIMethod'); $viewer = $this->requireViewer(); $out = array(); $last = null; $list = null; foreach ($methods as $method) { $app = $method->getApplicationName(); if ($app !== $last) { $last = $app; if ($list) { $out[] = $list; } $list = id(new PHUIObjectItemListView()); $list->setHeader($app); $app_object = $method->getApplication(); if ($app_object) { $app_name = $app_object->getName(); } else { $app_name = $app; } } $method_name = $method->getAPIMethodName(); $item = id(new PHUIObjectItemView()) ->setHeader($method_name) ->setHref($this->getApplicationURI('method/'.$method_name.'/')) ->addAttribute($method->getMethodSummary()); switch ($method->getMethodStatus()) { case ConduitAPIMethod::METHOD_STATUS_STABLE: break; case ConduitAPIMethod::METHOD_STATUS_UNSTABLE: $item->addIcon('fa-warning', pht('Unstable')); $item->setStatusIcon('fa-warning yellow'); break; case ConduitAPIMethod::METHOD_STATUS_DEPRECATED: $item->addIcon('fa-warning', pht('Deprecated')); $item->setStatusIcon('fa-warning red'); break; case ConduitAPIMethod::METHOD_STATUS_FROZEN: $item->addIcon('fa-archive', pht('Frozen')); $item->setStatusIcon('fa-archive grey'); break; } $list->addItem($item); } if ($list) { $out[] = $list; } $result = new PhabricatorApplicationSearchResultView(); $result->setContent($out); return $result; } } diff --git a/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php b/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php index 3129028c2e..4e0a89d266 100644 --- a/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php +++ b/src/applications/conpherence/query/ConpherenceThreadSearchEngine.php @@ -1,454 +1,454 @@ needParticipantCache(true) ->needProfileImage(true); } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setLabel(pht('Participants')) ->setKey('participants') ->setAliases(array('participant')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Rooms')) ->setKey('phids') ->setDescription(pht('Search by room titles.')) ->setDatasource(id(new ConpherenceThreadDatasource())), id(new PhabricatorSearchTextField()) ->setLabel(pht('Room Contains Words')) ->setKey('fulltext'), ); } protected function getDefaultFieldOrder() { return array( 'participants', '...', ); } protected function shouldShowOrderField() { return false; } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['participants']) { $query->withParticipantPHIDs($map['participants']); } if ($map['fulltext']) { $query->withFulltext($map['fulltext']); } if ($map['phids']) { $query->withPHIDs($map['phids']); } return $query; } protected function getURI($path) { return '/conpherence/search/'.$path; } protected function getBuiltinQueryNames() { $names = array(); $names['all'] = pht('All Rooms'); if ($this->requireViewer()->isLoggedIn()) { $names['participant'] = pht('Joined Rooms'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'participant': return $query->setParameter( 'participants', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $conpherences, PhabricatorSavedQuery $query) { $recent = mpull($conpherences, 'getRecentParticipantPHIDs'); return array_unique(array_mergev($recent)); } protected function renderResultList( array $conpherences, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($conpherences, 'ConpherenceThread'); $viewer = $this->requireViewer(); $policy_objects = ConpherenceThread::loadViewPolicyObjects( $viewer, $conpherences); $engines = array(); $fulltext = $query->getParameter('fulltext'); if (strlen($fulltext) && $conpherences) { $context = $this->loadContextMessages($conpherences, $fulltext); $author_phids = array(); foreach ($context as $phid => $messages) { $conpherence = $conpherences[$phid]; $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer) ->setContextObject($conpherence); foreach ($messages as $group) { foreach ($group as $message) { $xaction = $message['xaction']; if ($xaction) { $author_phids[] = $xaction->getAuthorPHID(); $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } } $engine->process(); $engines[$phid] = $engine; } $handles = $viewer->loadHandles($author_phids); $handles = iterator_to_array($handles); } else { $context = array(); } $content = array(); $list = new PHUIObjectItemListView(); $list->setUser($viewer); foreach ($conpherences as $conpherence_phid => $conpherence) { $created = phabricator_date($conpherence->getDateCreated(), $viewer); $title = $conpherence->getDisplayTitle($viewer); $monogram = $conpherence->getMonogram(); $icon_name = $conpherence->getPolicyIconName($policy_objects); $icon = id(new PHUIIconView()) ->setIcon($icon_name); if (!strlen($fulltext)) { $item = id(new PHUIObjectItemView()) ->setObjectName($conpherence->getMonogram()) ->setHeader($title) ->setHref('/'.$conpherence->getMonogram()) ->setObject($conpherence) ->setImageURI($conpherence->getProfileImageURI()) ->addIcon('none', $created) ->addIcon( 'none', pht('Messages: %d', $conpherence->getMessageCount())) ->addAttribute( array( $icon, ' ', pht( 'Last updated %s', phabricator_datetime($conpherence->getDateModified(), $viewer)), )); $list->addItem($item); } else { $messages = idx($context, $conpherence_phid); $box = array(); $list = null; if ($messages) { foreach ($messages as $group) { $rows = array(); foreach ($group as $message) { $xaction = $message['xaction']; if (!$xaction) { continue; } $view = id(new ConpherenceTransactionView()) ->setUser($viewer) ->setHandles($handles) ->setMarkupEngine($engines[$conpherence_phid]) ->setConpherenceThread($conpherence) ->setConpherenceTransaction($xaction) ->setSearchResult(true) ->addClass('conpherence-fulltext-result'); if ($message['match']) { $view->addClass('conpherence-fulltext-match'); } $rows[] = $view; } $box[] = id(new PHUIBoxView()) ->appendChild($rows) ->addClass('conpherence-fulltext-results'); } } $header = id(new PHUIHeaderView()) ->setHeader($title) ->setHeaderIcon($icon_name) ->setHref('/'.$monogram); $content[] = id(new PHUIObjectBoxView()) ->setHeader($header) ->appendChild($box); } } if ($list) { $content = $list; } else { $content = id(new PHUIBoxView()) ->addClass('conpherence-search-room-results') ->appendChild($content); } $result = new PhabricatorApplicationSearchResultView(); $result->setContent($content); $result->setNoDataString(pht('No results found.')); return $result; } private function loadContextMessages(array $threads, $fulltext) { $phids = mpull($threads, 'getPHID'); // We want to load a few messages for each thread in the result list, to // show some of the actual content hits to help the user find what they // are looking for. // This method is trying to batch this lookup in most cases, so we do // between one and "a handful" of queries instead of one per thread in // most cases. To do this: // // - Load a big block of results for all of the threads. // - If we didn't get a full block back, we have everything that matches // the query. Sort it out and exit. // - Otherwise, some threads had a ton of hits, so we might not be // getting everything we want (we could be getting back 1,000 hits for // the first thread). Remove any threads which we have enough results // for and try again. // - Repeat until we have everything or every thread has enough results. // // In the worst case, we could end up degrading to one query per thread, // but this is incredibly unlikely on real data. // Size of the result blocks we're going to load. $limit = 1000; // Number of messages we want for each thread. $want = 3; $need = $phids; $hits = array(); while ($need) { $rows = id(new ConpherenceFulltextQuery()) ->withThreadPHIDs($need) ->withFulltext($fulltext) ->setLimit($limit) ->execute(); foreach ($rows as $row) { $hits[$row['threadPHID']][] = $row; } if (count($rows) < $limit) { break; } foreach ($need as $key => $phid) { if (count($hits[$phid]) >= $want) { unset($need[$key]); } } } // Now that we have all the fulltext matches, throw away any extras that we // aren't going to render so we don't need to do lookups on them. foreach ($hits as $phid => $rows) { if (count($rows) > $want) { $hits[$phid] = array_slice($rows, 0, $want); } } // For each fulltext match, we want to render a message before and after // the match to give it some context. We already know the transactions // before each match because the rows have a "previousTransactionPHID", // but we need to do one more query to figure out the transactions after // each match. // Collect the transactions we want to find the next transactions for. $after = array(); foreach ($hits as $phid => $rows) { foreach ($rows as $row) { $after[] = $row['transactionPHID']; } } // Look up the next transactions. if ($after) { $after_rows = id(new ConpherenceFulltextQuery()) ->withPreviousTransactionPHIDs($after) ->execute(); } else { $after_rows = array(); } // Build maps from PHIDs to the previous and next PHIDs. $prev_map = array(); $next_map = array(); foreach ($after_rows as $row) { $next_map[$row['previousTransactionPHID']] = $row['transactionPHID']; } foreach ($hits as $phid => $rows) { foreach ($rows as $row) { $prev = $row['previousTransactionPHID']; if ($prev) { $prev_map[$row['transactionPHID']] = $prev; $next_map[$prev] = $row['transactionPHID']; } } } // Now we're going to collect the actual transaction PHIDs, in order, that // we want to show for each thread. $groups = array(); foreach ($hits as $thread_phid => $rows) { $rows = ipull($rows, null, 'transactionPHID'); $done = array(); foreach ($rows as $phid => $row) { if (isset($done[$phid])) { continue; } $done[$phid] = true; $group = array(); // Walk backward, finding all the previous results. We can just keep // going until we run out of results because we've only loaded things // that we want to show. $prev = $phid; while (true) { if (!isset($prev_map[$prev])) { // No previous transaction, so we're done. break; } $prev = $prev_map[$prev]; if (isset($rows[$prev])) { $match = true; $done[$prev] = true; } else { $match = false; } $group[] = array( 'phid' => $prev, 'match' => $match, ); } if (count($group) > 1) { $group = array_reverse($group); } $group[] = array( 'phid' => $phid, 'match' => true, ); $next = $phid; while (true) { if (!isset($next_map[$next])) { break; } $next = $next_map[$next]; if (isset($rows[$next])) { $match = true; $done[$next] = true; } else { $match = false; } $group[] = array( 'phid' => $next, 'match' => $match, ); } $groups[$thread_phid][] = $group; } } // Load all the actual transactions we need. $xaction_phids = array(); foreach ($groups as $thread_phid => $group) { foreach ($group as $list) { foreach ($list as $item) { $xaction_phids[] = $item['phid']; } } } if ($xaction_phids) { $xactions = id(new ConpherenceTransactionQuery()) ->setViewer($this->requireViewer()) ->withPHIDs($xaction_phids) ->needComments(true) ->execute(); $xactions = mpull($xactions, null, 'getPHID'); } else { $xactions = array(); } foreach ($groups as $thread_phid => $group) { foreach ($group as $key => $list) { foreach ($list as $lkey => $item) { $xaction = idx($xactions, $item['phid']); if ($xaction->shouldHide()) { continue; } $groups[$thread_phid][$key][$lkey]['xaction'] = $xaction; } } } // TODO: Sort the groups chronologically? return $groups; } } diff --git a/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php b/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php index 89e77997d8..87e908b9c2 100644 --- a/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php +++ b/src/applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php @@ -1,154 +1,158 @@ newQuery(); if ($map['status']) { switch ($map['status']) { case 'active': $query->withArchived(false); break; case 'archived': $query->withArchived(true); break; default: break; } } if ($map['paneltype']) { $query->withPanelTypes(array($map['paneltype'])); } if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['name'] !== null) { $query->withNameNgrams($map['name']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('name') ->setDescription(pht('Search for panels by name substring.')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Authored By')) ->setKey('authorPHIDs') ->setDatasource(new PhabricatorPeopleUserFunctionDatasource()), id(new PhabricatorSearchSelectField()) ->setKey('status') ->setLabel(pht('Status')) ->setOptions( id(new PhabricatorDashboardPanel()) ->getStatuses()), id(new PhabricatorSearchSelectField()) ->setKey('paneltype') ->setLabel(pht('Panel Type')) ->setOptions( id(new PhabricatorDashboardPanel()) ->getPanelTypes()), ); } protected function getURI($path) { return '/dashboard/panel/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } $names['active'] = pht('Active Panels'); $names['all'] = pht('All Panels'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); switch ($query_key) { case 'active': return $query->setParameter('status', 'active'); case 'authored': return $query->setParameter( 'authorPHIDs', array( $viewer->getPHID(), )); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $panels, PhabricatorSavedQuery $query, array $handles) { $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $list->setUser($viewer); foreach ($panels as $panel) { $item = id(new PHUIObjectItemView()) ->setObjectName($panel->getMonogram()) ->setHeader($panel->getName()) ->setHref('/'.$panel->getMonogram()) ->setObject($panel); $impl = $panel->getImplementation(); if ($impl) { $type_text = $impl->getPanelTypeName(); } else { $type_text = nonempty($panel->getPanelType(), pht('Unknown Type')); } $item->addAttribute($type_text); $properties = $panel->getProperties(); $class = idx($properties, 'class'); $item->addAttribute($class); if ($panel->getIsArchived()) { $item->setDisabled(true); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No panels found.')); return $result; } } diff --git a/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php b/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php index 6061a0ab8a..a854b066f8 100644 --- a/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php +++ b/src/applications/dashboard/query/PhabricatorDashboardSearchEngine.php @@ -1,179 +1,183 @@ needPanels(true); } + public function canUseInPanelContext() { + return false; + } + protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('name') ->setDescription(pht('Search for dashboards by name substring.')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Authored By')) ->setKey('authorPHIDs') ->setDatasource(new PhabricatorPeopleUserFunctionDatasource()), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) ->setOptions(PhabricatorDashboard::getStatusNameMap()), ); } protected function getURI($path) { return '/dashboard/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } $names['open'] = pht('Active Dashboards'); $names['all'] = pht('All Dashboards'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); switch ($query_key) { case 'all': return $query; case 'authored': return $query->setParameter( 'authorPHIDs', array( $viewer->getPHID(), )); case 'open': return $query->setParameter( 'statuses', array( PhabricatorDashboard::STATUS_ACTIVE, )); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['name'] !== null) { $query->withNameNgrams($map['name']); } return $query; } protected function renderResultList( array $dashboards, PhabricatorSavedQuery $query, array $handles) { $viewer = $this->requireViewer(); $phids = array(); foreach ($dashboards as $dashboard) { $author_phid = $dashboard->getAuthorPHID(); if ($author_phid) { $phids[] = $author_phid; } } $handles = $viewer->loadHandles($phids); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($dashboards as $dashboard) { $id = $dashboard->getID(); $item = id(new PHUIObjectItemView()) ->setUser($viewer) ->setHeader($dashboard->getName()) ->setHref($this->getApplicationURI("view/{$id}/")) ->setObject($dashboard); if ($dashboard->isArchived()) { $item->setDisabled(true); } $panels = $dashboard->getPanels(); foreach ($panels as $panel) { $item->addAttribute($panel->getName()); } if (empty($panels)) { $empty = phutil_tag('em', array(), pht('No panels.')); $item->addAttribute($empty); } $icon = id(new PHUIIconView()) ->setIcon($dashboard->getIcon()) ->setBackground('bg-dark'); $item->setImageIcon($icon); $item->setEpoch($dashboard->getDateModified()); $author_phid = $dashboard->getAuthorPHID(); $author_name = $handles[$author_phid]->renderLink(); $item->addByline(pht('Author: %s', $author_name)); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No dashboards found.')); return $result; } protected function getNewUserBody() { $create_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Create a Dashboard')) ->setHref('/dashboard/create/') ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Customize your homepage with different panels and '. 'search queries.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/diviner/query/DivinerAtomSearchEngine.php b/src/applications/diviner/query/DivinerAtomSearchEngine.php index cffdd3592d..35caf20a63 100644 --- a/src/applications/diviner/query/DivinerAtomSearchEngine.php +++ b/src/applications/diviner/query/DivinerAtomSearchEngine.php @@ -1,154 +1,158 @@ setParameter( 'bookPHIDs', $this->readPHIDsFromRequest($request, 'bookPHIDs')); $saved->setParameter( 'repositoryPHIDs', $this->readPHIDsFromRequest($request, 'repositoryPHIDs')); $saved->setParameter('name', $request->getStr('name')); $saved->setParameter( 'types', $this->readListFromRequest($request, 'types')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new DivinerAtomQuery()); $books = $saved->getParameter('bookPHIDs'); if ($books) { $query->withBookPHIDs($books); } $repository_phids = $saved->getParameter('repositoryPHIDs'); if ($repository_phids) { $query->withRepositoryPHIDs($repository_phids); } $name = $saved->getParameter('name'); if ($name) { $query->withNameContains($name); } $types = $saved->getParameter('types'); if ($types) { $query->withTypes($types); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved) { $form->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Name Contains')) ->setName('name') ->setValue($saved->getParameter('name'))); $all_types = array(); foreach (DivinerAtom::getAllTypes() as $type) { $all_types[$type] = DivinerAtom::getAtomTypeNameString($type); } asort($all_types); $types = $saved->getParameter('types', array()); $types = array_fuse($types); $type_control = id(new AphrontFormCheckboxControl()) ->setLabel(pht('Types')); foreach ($all_types as $type => $name) { $type_control->addCheckbox( 'types[]', $type, $name, isset($types[$type])); } $form->appendChild($type_control); $form->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new DivinerBookDatasource()) ->setName('bookPHIDs') ->setLabel(pht('Books')) ->setValue($saved->getParameter('bookPHIDs'))); $form->appendControl( id(new AphrontFormTokenizerControl()) ->setLabel(pht('Repositories')) ->setName('repositoryPHIDs') ->setDatasource(new DiffusionRepositoryDatasource()) ->setValue($saved->getParameter('repositoryPHIDs'))); } protected function getURI($path) { return '/diviner/'.$path; } protected function getBuiltinQueryNames() { return array( 'all' => pht('All Atoms'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $symbols, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($symbols, 'DivinerLiveSymbol'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($symbols as $symbol) { $type = $symbol->getType(); $type_name = DivinerAtom::getAtomTypeNameString($type); $item = id(new PHUIObjectItemView()) ->setHeader($symbol->getTitle()) ->setHref($symbol->getURI()) ->addAttribute($symbol->getSummary()) ->addIcon('none', $type_name); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No books found.')); return $result; } } diff --git a/src/applications/files/query/PhabricatorFileSearchEngine.php b/src/applications/files/query/PhabricatorFileSearchEngine.php index f2193d3beb..1f2f2de4b3 100644 --- a/src/applications/files/query/PhabricatorFileSearchEngine.php +++ b/src/applications/files/query/PhabricatorFileSearchEngine.php @@ -1,200 +1,204 @@ setKey('authorPHIDs') ->setAliases(array('author', 'authors')) ->setLabel(pht('Authors')), id(new PhabricatorSearchThreeStateField()) ->setKey('explicit') ->setLabel(pht('Upload Source')) ->setOptions( pht('(Show All)'), pht('Show Only Manually Uploaded Files'), pht('Hide Manually Uploaded Files')), id(new PhabricatorSearchDateField()) ->setKey('createdStart') ->setLabel(pht('Created After')), id(new PhabricatorSearchDateField()) ->setKey('createdEnd') ->setLabel(pht('Created Before')), ); } protected function getDefaultFieldOrder() { return array( '...', 'createdStart', 'createdEnd', ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['explicit'] !== null) { $query->showOnlyExplicitUploads($map['explicit']); } if ($map['createdStart']) { $query->withDateCreatedAfter($map['createdStart']); } if ($map['createdEnd']) { $query->withDateCreatedBefore($map['createdEnd']); } return $query; } protected function getURI($path) { return '/file/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } $names += array( 'all' => pht('All'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'authored': $author_phid = array($this->requireViewer()->getPHID()); return $query ->setParameter('authorPHIDs', $author_phid) ->setParameter('explicit', true); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $files, PhabricatorSavedQuery $query) { return mpull($files, 'getAuthorPHID'); } protected function renderResultList( array $files, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($files, 'PhabricatorFile'); $request = $this->getRequest(); if ($request) { $highlighted_ids = $request->getStrList('h'); } else { $highlighted_ids = array(); } $viewer = $this->requireViewer(); $highlighted_ids = array_fill_keys($highlighted_ids, true); $list_view = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($files as $file) { $id = $file->getID(); $phid = $file->getPHID(); $name = $file->getName(); $file_uri = $this->getApplicationURI("/info/{$phid}/"); $date_created = phabricator_date($file->getDateCreated(), $viewer); $author_phid = $file->getAuthorPHID(); if ($author_phid) { $author_link = $handles[$author_phid]->renderLink(); $uploaded = pht('Uploaded by %s on %s', $author_link, $date_created); } else { $uploaded = pht('Uploaded on %s', $date_created); } $item = id(new PHUIObjectItemView()) ->setObject($file) ->setObjectName("F{$id}") ->setHeader($name) ->setHref($file_uri) ->addAttribute($uploaded) ->addIcon('none', phutil_format_bytes($file->getByteSize())); $ttl = $file->getTTL(); if ($ttl !== null) { $item->addIcon('blame', pht('Temporary')); } if ($file->getIsPartial()) { $item->addIcon('fa-exclamation-triangle orange', pht('Partial')); } if (isset($highlighted_ids[$id])) { $item->setEffect('highlighted'); } $list_view->addItem($item); } $list_view->appendChild(id(new PhabricatorGlobalUploadTargetView()) ->setUser($viewer)); $result = new PhabricatorApplicationSearchResultView(); $result->setContent($list_view); return $result; } protected function getNewUserBody() { $create_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Upload a File')) ->setHref('/file/upload/') ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Just a place for files.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/herald/query/HeraldTranscriptSearchEngine.php b/src/applications/herald/query/HeraldTranscriptSearchEngine.php index cc0d620394..e35620f0da 100644 --- a/src/applications/herald/query/HeraldTranscriptSearchEngine.php +++ b/src/applications/herald/query/HeraldTranscriptSearchEngine.php @@ -1,143 +1,147 @@ getStrList('objectMonograms'); $saved->setParameter('objectMonograms', $object_monograms); $ids = $request->getStrList('ids'); foreach ($ids as $key => $id) { if (!$id || !is_numeric($id)) { unset($ids[$key]); } else { $ids[$key] = $id; } } $saved->setParameter('ids', $ids); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new HeraldTranscriptQuery()); $object_monograms = $saved->getParameter('objectMonograms'); if ($object_monograms) { $objects = id(new PhabricatorObjectQuery()) ->setViewer($this->requireViewer()) ->withNames($object_monograms) ->execute(); $query->withObjectPHIDs(mpull($objects, 'getPHID')); } $ids = $saved->getParameter('ids'); if ($ids) { $query->withIDs($ids); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved) { $object_monograms = $saved->getParameter('objectMonograms', array()); $ids = $saved->getParameter('ids', array()); $form ->appendChild( id(new AphrontFormTextControl()) ->setName('objectMonograms') ->setLabel(pht('Object Monograms')) ->setValue(implode(', ', $object_monograms))) ->appendChild( id(new AphrontFormTextControl()) ->setName('ids') ->setLabel(pht('Transcript IDs')) ->setValue(implode(', ', $ids))); } protected function getURI($path) { return '/herald/transcript/'.$path; } protected function getBuiltinQueryNames() { return array( 'all' => pht('All Transcripts'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer_phid = $this->requireViewer()->getPHID(); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $transcripts, PhabricatorSavedQuery $query) { return mpull($transcripts, 'getObjectPHID'); } protected function renderResultList( array $transcripts, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($transcripts, 'HeraldTranscript'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($transcripts as $xscript) { $view_href = phutil_tag( 'a', array( 'href' => '/herald/transcript/'.$xscript->getID().'/', ), pht('View Full Transcript')); $item = new PHUIObjectItemView(); $item->setObjectName($xscript->getID()); $item->setHeader($view_href); if ($xscript->getDryRun()) { $item->addAttribute(pht('Dry Run')); } $item->addAttribute($handles[$xscript->getObjectPHID()]->renderLink()); $item->addAttribute( pht('%s ms', new PhutilNumber((int)(1000 * $xscript->getDuration())))); $item->addIcon( 'none', phabricator_datetime($xscript->getTime(), $viewer)); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No transcripts found.')); return $result; } } diff --git a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php index 5246f32a0e..d8f5ab493a 100644 --- a/src/applications/maniphest/query/ManiphestTaskSearchEngine.php +++ b/src/applications/maniphest/query/ManiphestTaskSearchEngine.php @@ -1,427 +1,427 @@ isBoardView = $is_board_view; return $this; } public function getIsBoardView() { return $this->isBoardView; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function getBaseURI() { return $this->baseURI; } public function setShowBatchControls($show_batch_controls) { $this->showBatchControls = $show_batch_controls; return $this; } public function getResultTypeDescription() { - return pht('Tasks'); + return pht('Maniphest Tasks'); } public function getApplicationClassName() { return 'PhabricatorManiphestApplication'; } public function newQuery() { return id(new ManiphestTaskQuery()) ->needProjectPHIDs(true); } protected function buildCustomSearchFields() { return array( id(new PhabricatorOwnersSearchField()) ->setLabel(pht('Assigned To')) ->setKey('assignedPHIDs') ->setConduitKey('assigned') ->setAliases(array('assigned')) ->setDescription( pht('Search for tasks owned by a user from a list.')), id(new PhabricatorUsersSearchField()) ->setLabel(pht('Authors')) ->setKey('authorPHIDs') ->setAliases(array('author', 'authors')) ->setDescription( pht('Search for tasks with given authors.')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Statuses')) ->setKey('statuses') ->setAliases(array('status')) ->setDescription( pht('Search for tasks with given statuses.')) ->setDatasource(new ManiphestTaskStatusFunctionDatasource()), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Priorities')) ->setKey('priorities') ->setAliases(array('priority')) ->setDescription( pht('Search for tasks with given priorities.')) ->setConduitParameterType(new ConduitIntListParameterType()) ->setDatasource(new ManiphestTaskPriorityDatasource()), id(new PhabricatorSearchTextField()) ->setLabel(pht('Contains Words')) ->setKey('fulltext'), id(new PhabricatorSearchThreeStateField()) ->setLabel(pht('Open Parents')) ->setKey('hasParents') ->setAliases(array('blocking')) ->setOptions( pht('(Show All)'), pht('Show Only Tasks With Open Parents'), pht('Show Only Tasks Without Open Parents')), id(new PhabricatorSearchThreeStateField()) ->setLabel(pht('Open Subtasks')) ->setKey('hasSubtasks') ->setAliases(array('blocked')) ->setOptions( pht('(Show All)'), pht('Show Only Tasks With Open Subtasks'), pht('Show Only Tasks Without Open Subtasks')), id(new PhabricatorIDsSearchField()) ->setLabel(pht('Parent IDs')) ->setKey('parentIDs') ->setAliases(array('parentID')), id(new PhabricatorIDsSearchField()) ->setLabel(pht('Subtask IDs')) ->setKey('subtaskIDs') ->setAliases(array('subtaskID')), id(new PhabricatorSearchSelectField()) ->setLabel(pht('Group By')) ->setKey('group') ->setOptions($this->getGroupOptions()), id(new PhabricatorSearchDateField()) ->setLabel(pht('Created After')) ->setKey('createdStart'), id(new PhabricatorSearchDateField()) ->setLabel(pht('Created Before')) ->setKey('createdEnd'), id(new PhabricatorSearchDateField()) ->setLabel(pht('Updated After')) ->setKey('modifiedStart'), id(new PhabricatorSearchDateField()) ->setLabel(pht('Updated Before')) ->setKey('modifiedEnd'), id(new PhabricatorSearchTextField()) ->setLabel(pht('Page Size')) ->setKey('limit'), ); } protected function getDefaultFieldOrder() { return array( 'assignedPHIDs', 'projectPHIDs', 'authorPHIDs', 'subscriberPHIDs', 'statuses', 'priorities', 'fulltext', 'hasParents', 'hasSubtasks', 'parentIDs', 'subtaskIDs', 'group', 'order', 'ids', '...', 'createdStart', 'createdEnd', 'modifiedStart', 'modifiedEnd', 'limit', ); } protected function getHiddenFields() { $keys = array(); if ($this->getIsBoardView()) { $keys[] = 'group'; $keys[] = 'order'; $keys[] = 'limit'; } return $keys; } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['assignedPHIDs']) { $query->withOwners($map['assignedPHIDs']); } if ($map['authorPHIDs']) { $query->withAuthors($map['authorPHIDs']); } if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['priorities']) { $query->withPriorities($map['priorities']); } if ($map['createdStart']) { $query->withDateCreatedAfter($map['createdStart']); } if ($map['createdEnd']) { $query->withDateCreatedBefore($map['createdEnd']); } if ($map['modifiedStart']) { $query->withDateModifiedAfter($map['modifiedStart']); } if ($map['modifiedEnd']) { $query->withDateModifiedBefore($map['modifiedEnd']); } if ($map['hasParents'] !== null) { $query->withOpenParents($map['hasParents']); } if ($map['hasSubtasks'] !== null) { $query->withOpenSubtasks($map['hasSubtasks']); } if (strlen($map['fulltext'])) { $query->withFullTextSearch($map['fulltext']); } if ($map['parentIDs']) { $query->withParentTaskIDs($map['parentIDs']); } if ($map['subtaskIDs']) { $query->withSubtaskIDs($map['subtaskIDs']); } $group = idx($map, 'group'); $group = idx($this->getGroupValues(), $group); if ($group) { $query->setGroupBy($group); } else { $query->setGroupBy(head($this->getGroupValues())); } if ($map['ids']) { $ids = $map['ids']; foreach ($ids as $key => $id) { $id = trim($id, ' Tt'); if (!$id || !is_numeric($id)) { unset($ids[$key]); } else { $ids[$key] = $id; } } if ($ids) { $query->withIDs($ids); } } return $query; } protected function getURI($path) { if ($this->baseURI) { return $this->baseURI.$path; } return '/maniphest/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['assigned'] = pht('Assigned'); $names['authored'] = pht('Authored'); $names['subscribed'] = pht('Subscribed'); } $names['open'] = pht('Open Tasks'); $names['all'] = pht('All Tasks'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer_phid = $this->requireViewer()->getPHID(); switch ($query_key) { case 'all': return $query; case 'assigned': return $query ->setParameter('assignedPHIDs', array($viewer_phid)) ->setParameter( 'statuses', ManiphestTaskStatus::getOpenStatusConstants()); case 'subscribed': return $query ->setParameter('subscriberPHIDs', array($viewer_phid)) ->setParameter( 'statuses', ManiphestTaskStatus::getOpenStatusConstants()); case 'open': return $query ->setParameter( 'statuses', ManiphestTaskStatus::getOpenStatusConstants()); case 'authored': return $query ->setParameter('authorPHIDs', array($viewer_phid)) ->setParameter('order', 'created') ->setParameter('group', 'none'); } return parent::buildSavedQueryFromBuiltin($query_key); } private function getGroupOptions() { return array( 'priority' => pht('Priority'), 'assigned' => pht('Assigned'), 'status' => pht('Status'), 'project' => pht('Project'), 'none' => pht('None'), ); } private function getGroupValues() { return array( 'priority' => ManiphestTaskQuery::GROUP_PRIORITY, 'assigned' => ManiphestTaskQuery::GROUP_OWNER, 'status' => ManiphestTaskQuery::GROUP_STATUS, 'project' => ManiphestTaskQuery::GROUP_PROJECT, 'none' => ManiphestTaskQuery::GROUP_NONE, ); } protected function renderResultList( array $tasks, PhabricatorSavedQuery $saved, array $handles) { $viewer = $this->requireViewer(); if ($this->isPanelContext()) { $can_edit_priority = false; $can_bulk_edit = false; } else { $can_edit_priority = PhabricatorPolicyFilter::hasCapability( $viewer, $this->getApplication(), ManiphestEditPriorityCapability::CAPABILITY); $can_bulk_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $this->getApplication(), ManiphestBulkEditCapability::CAPABILITY); } $list = id(new ManiphestTaskResultListView()) ->setUser($viewer) ->setTasks($tasks) ->setSavedQuery($saved) ->setCanEditPriority($can_edit_priority) ->setCanBatchEdit($can_bulk_edit) ->setShowBatchControls($this->showBatchControls); $result = new PhabricatorApplicationSearchResultView(); $result->setContent($list); return $result; } protected function willUseSavedQuery(PhabricatorSavedQuery $saved) { // The 'withUnassigned' parameter may be present in old saved queries from // before parameterized typeaheads, and is retained for compatibility. We // could remove it by migrating old saved queries. $assigned_phids = $saved->getParameter('assignedPHIDs', array()); if ($saved->getParameter('withUnassigned')) { $assigned_phids[] = PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN; } $saved->setParameter('assignedPHIDs', $assigned_phids); // The 'projects' and other parameters may be present in old saved queries // from before parameterized typeaheads. $project_phids = $saved->getParameter('projectPHIDs', array()); $old = $saved->getParameter('projects', array()); foreach ($old as $phid) { $project_phids[] = $phid; } $all = $saved->getParameter('allProjectPHIDs', array()); foreach ($all as $phid) { $project_phids[] = $phid; } $any = $saved->getParameter('anyProjectPHIDs', array()); foreach ($any as $phid) { $project_phids[] = 'any('.$phid.')'; } $not = $saved->getParameter('excludeProjectPHIDs', array()); foreach ($not as $phid) { $project_phids[] = 'not('.$phid.')'; } $users = $saved->getParameter('userProjectPHIDs', array()); foreach ($users as $phid) { $project_phids[] = 'projects('.$phid.')'; } $no = $saved->getParameter('withNoProject'); if ($no) { $project_phids[] = 'null()'; } $saved->setParameter('projectPHIDs', $project_phids); } protected function getNewUserBody() { $viewer = $this->requireViewer(); $create_button = id(new ManiphestEditEngine()) ->setViewer($viewer) ->newNUXBUtton(pht('Create a Task')); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Use Maniphest to track bugs, features, todos, or anything else '. 'you need to get done. Tasks assigned to you will appear here.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php b/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php index 11ca1116ea..df7774aae2 100644 --- a/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php +++ b/src/applications/metamta/query/PhabricatorMetaMTAMailSearchEngine.php @@ -1,129 +1,133 @@ setLabel(pht('Actors')) ->setKey('actorPHIDs') ->setAliases(array('actor', 'actors')), id(new PhabricatorUsersSearchField()) ->setLabel(pht('Recipients')) ->setKey('recipientPHIDs') ->setAliases(array('recipient', 'recipients')), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['actorPHIDs']) { $query->withActorPHIDs($map['actorPHIDs']); } if ($map['recipientPHIDs']) { $query->withRecipientPHIDs($map['recipientPHIDs']); } return $query; } protected function getURI($path) { return '/mail/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'inbox' => pht('Inbox'), 'outbox' => pht('Outbox'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $viewer = $this->requireViewer(); $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'inbox': return $query->setParameter( 'recipientPHIDs', array($viewer->getPHID())); case 'outbox': return $query->setParameter( 'actorPHIDs', array($viewer->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $objects, PhabricatorSavedQuery $query) { $phids = array(); foreach ($objects as $mail) { $phids[] = $mail->getExpandedRecipientPHIDs(); } return array_mergev($phids); } protected function renderResultList( array $mails, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($mails, 'PhabricatorMetaMTAMail'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($mails as $mail) { if ($mail->hasSensitiveContent()) { $header = phutil_tag('em', array(), pht('Content Redacted')); } else { $header = $mail->getSubject(); } $item = id(new PHUIObjectItemView()) ->setUser($viewer) ->setObject($mail) ->setEpoch($mail->getDateCreated()) ->setObjectName(pht('Mail %d', $mail->getID())) ->setHeader($header) ->setHref($this->getURI('detail/'.$mail->getID().'/')); $status = $mail->getStatus(); $status_name = PhabricatorMailOutboundStatus::getStatusName($status); $status_icon = PhabricatorMailOutboundStatus::getStatusIcon($status); $status_color = PhabricatorMailOutboundStatus::getStatusColor($status); $item->setStatusIcon($status_icon.' '.$status_color, $status_name); $list->addItem($item); } return id(new PhabricatorApplicationSearchResultView()) ->setContent($list); } } diff --git a/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php b/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php index 3cb027fe4f..e07b1ea2c2 100644 --- a/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php +++ b/src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php @@ -1,103 +1,107 @@ newQuery(); if ($map['creatorPHIDs']) { $query->withCreatorPHIDs($map['creatorPHIDs']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setAliases(array('creators')) ->setKey('creatorPHIDs') ->setConduitKey('creators') ->setLabel(pht('Creators')) ->setDescription( pht('Search for applications created by particular users.')), ); } protected function getURI($path) { return '/oauthserver/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['created'] = pht('Created'); } $names['all'] = pht('All Applications'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'created': return $query->setParameter( 'creatorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $clients, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($clients, 'PhabricatorOAuthServerClient'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($clients as $client) { $item = id(new PHUIObjectItemView()) ->setObjectName(pht('Application %d', $client->getID())) ->setHeader($client->getName()) ->setHref($client->getViewURI()) ->setObject($client); if ($client->getIsDisabled()) { $item->setDisabled(true); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No clients found.')); return $result; } } diff --git a/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php b/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php index 728c3f42a8..d6001419b4 100644 --- a/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php +++ b/src/applications/owners/query/PhabricatorOwnersPackageSearchEngine.php @@ -1,178 +1,182 @@ setLabel(pht('Authority')) ->setKey('authorityPHIDs') ->setAliases(array('authority', 'authorities')) ->setConduitKey('owners') ->setDescription( pht('Search for packages with specific owners.')) ->setDatasource(new PhabricatorProjectOrUserDatasource()), id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('name') ->setDescription(pht('Search for packages by name substrings.')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Repositories')) ->setKey('repositoryPHIDs') ->setConduitKey('repositories') ->setAliases(array('repository', 'repositories')) ->setDescription( pht('Search for packages by included repositories.')) ->setDatasource(new DiffusionRepositoryDatasource()), id(new PhabricatorSearchStringListField()) ->setLabel(pht('Paths')) ->setKey('paths') ->setAliases(array('path')) ->setDescription( pht('Search for packages affecting specific paths.')), id(new PhabricatorSearchCheckboxesField()) ->setKey('statuses') ->setLabel(pht('Status')) ->setDescription( pht('Search for active or archived packages.')) ->setOptions( id(new PhabricatorOwnersPackage()) ->getStatusNameMap()), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorityPHIDs']) { $query->withAuthorityPHIDs($map['authorityPHIDs']); } if ($map['repositoryPHIDs']) { $query->withRepositoryPHIDs($map['repositoryPHIDs']); } if ($map['paths']) { $query->withPaths($map['paths']); } if ($map['statuses']) { $query->withStatuses($map['statuses']); } if (strlen($map['name'])) { $query->withNameNgrams($map['name']); } return $query; } protected function getURI($path) { return '/owners/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['authority'] = pht('Owned'); } $names += array( 'active' => pht('Active Packages'), 'all' => pht('All Packages'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'active': return $query->setParameter( 'statuses', array( PhabricatorOwnersPackage::STATUS_ACTIVE, )); case 'authority': return $query->setParameter( 'authorityPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $packages, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($packages, 'PhabricatorOwnersPackage'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($packages as $package) { $id = $package->getID(); $item = id(new PHUIObjectItemView()) ->setObject($package) ->setObjectName($package->getMonogram()) ->setHeader($package->getName()) ->setHref($package->getURI()); if ($package->isArchived()) { $item->setDisabled(true); } $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No packages found.')); return $result; } protected function getNewUserBody() { $create_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Create a Package')) ->setHref('/owners/edit/') ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Group sections of a codebase into packages for re-use in other '. 'areas of Phabricator, like Herald rules.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php index e01c8db503..817321dec1 100644 --- a/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php +++ b/src/applications/packages/query/PhabricatorPackagesPackageSearchEngine.php @@ -1,89 +1,93 @@ newQuery(); if ($map['match'] !== null) { $query->withNameNgrams($map['match']); } if ($map['publisherPHIDs']) { $query->withPublisherPHIDs($map['publisherPHIDs']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('match') ->setDescription(pht('Search for packages by name substring.')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Publishers')) ->setKey('publisherPHIDs') ->setAliases(array('publisherPHID', 'publisher', 'publishers')) ->setDatasource(new PhabricatorPackagesPublisherDatasource()) ->setDescription(pht('Search for packages by publisher.')), ); } protected function getURI($path) { return '/packages/package/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Packages'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $packages, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($packages, 'PhabricatorPackagesPackage'); $viewer = $this->requireViewer(); $list = id(new PhabricatorPackagesPackageListView()) ->setViewer($viewer) ->setPackages($packages) ->newListView(); return id(new PhabricatorApplicationSearchResultView()) ->setObjectList($list) ->setNoDataString(pht('No packages found.')); } } diff --git a/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php index f11738f730..be7b83f5fc 100644 --- a/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php +++ b/src/applications/packages/query/PhabricatorPackagesPublisherSearchEngine.php @@ -1,80 +1,84 @@ newQuery(); if ($map['match'] !== null) { $query->withNameNgrams($map['match']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('match') ->setDescription(pht('Search for publishers by name substring.')), ); } protected function getURI($path) { return '/packages/publisher/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Publishers'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $publishers, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($publishers, 'PhabricatorPackagesPublisher'); $viewer = $this->requireViewer(); $list = id(new PhabricatorPackagesPublisherListView()) ->setViewer($viewer) ->setPublishers($publishers) ->newListView(); return id(new PhabricatorApplicationSearchResultView()) ->setObjectList($list) ->setNoDataString(pht('No publishers found.')); } } diff --git a/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php b/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php index da1581bf80..b3592ffd70 100644 --- a/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php +++ b/src/applications/packages/query/PhabricatorPackagesVersionSearchEngine.php @@ -1,88 +1,92 @@ newQuery(); if ($map['match'] !== null) { $query->withNameNgrams($map['match']); } if ($map['packagePHIDs']) { $query->withPackagePHIDs($map['packagePHIDs']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('match') ->setDescription(pht('Search for versions by name substring.')), id(new PhabricatorSearchDatasourceField()) ->setLabel(pht('Packages')) ->setKey('packagePHIDs') ->setAliases(array('packagePHID', 'package', 'packages')) ->setDatasource(new PhabricatorPackagesPackageDatasource()) ->setDescription(pht('Search for versions by package.')), ); } protected function getURI($path) { return '/packages/version/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Versions'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $versions, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($versions, 'PhabricatorPackagesVersion'); $viewer = $this->requireViewer(); $list = id(new PhabricatorPackagesVersionListView()) ->setViewer($viewer) ->setVersions($versions) ->newListView(); return id(new PhabricatorApplicationSearchResultView()) ->setObjectList($list) ->setNoDataString(pht('No versions found.')); } } diff --git a/src/applications/phrequent/query/PhrequentSearchEngine.php b/src/applications/phrequent/query/PhrequentSearchEngine.php index d137c40b64..46f7ae769c 100644 --- a/src/applications/phrequent/query/PhrequentSearchEngine.php +++ b/src/applications/phrequent/query/PhrequentSearchEngine.php @@ -1,198 +1,203 @@ getParameter('limit', 1000); } public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); $saved->setParameter( 'userPHIDs', $this->readUsersFromRequest($request, 'users')); $saved->setParameter('ended', $request->getStr('ended')); $saved->setParameter('order', $request->getStr('order')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhrequentUserTimeQuery()) ->needPreemptingEvents(true); $user_phids = $saved->getParameter('userPHIDs'); if ($user_phids) { $query->withUserPHIDs($user_phids); } $ended = $saved->getParameter('ended'); if ($ended != null) { $query->withEnded($ended); } $order = $saved->getParameter('order'); if ($order != null) { $query->setOrder($order); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $user_phids = $saved_query->getParameter('userPHIDs', array()); $ended = $saved_query->getParameter( 'ended', PhrequentUserTimeQuery::ENDED_ALL); $order = $saved_query->getParameter( 'order', PhrequentUserTimeQuery::ORDER_ENDED_DESC); $form ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) ->setName('users') ->setLabel(pht('Users')) ->setValue($user_phids)) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Ended')) ->setName('ended') ->setValue($ended) ->setOptions(PhrequentUserTimeQuery::getEndedSearchOptions())) ->appendChild( id(new AphrontFormSelectControl()) ->setLabel(pht('Order')) ->setName('order') ->setValue($order) ->setOptions(PhrequentUserTimeQuery::getOrderSearchOptions())); } protected function getURI($path) { return '/phrequent/'.$path; } protected function getBuiltinQueryNames() { return array( 'tracking' => pht('Currently Tracking'), 'all' => pht('All Tracked'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query ->setParameter('order', PhrequentUserTimeQuery::ORDER_ENDED_DESC); case 'tracking': return $query ->setParameter('ended', PhrequentUserTimeQuery::ENDED_NO) ->setParameter('order', PhrequentUserTimeQuery::ORDER_ENDED_DESC); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function getRequiredHandlePHIDsForResultList( array $usertimes, PhabricatorSavedQuery $query) { return array_mergev( array( mpull($usertimes, 'getUserPHID'), mpull($usertimes, 'getObjectPHID'), )); } protected function renderResultList( array $usertimes, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($usertimes, 'PhrequentUserTime'); $viewer = $this->requireViewer(); $view = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($usertimes as $usertime) { $item = new PHUIObjectItemView(); if ($usertime->getObjectPHID() === null) { $item->setHeader($usertime->getNote()); } else { $obj = $handles[$usertime->getObjectPHID()]; $item->setHeader($obj->getLinkName()); $item->setHref($obj->getURI()); } $item->setObject($usertime); $item->addByline( pht( 'Tracked: %s', $handles[$usertime->getUserPHID()]->renderLink())); $started_date = phabricator_date($usertime->getDateStarted(), $viewer); $item->addIcon('none', $started_date); $block = new PhrequentTimeBlock(array($usertime)); $time_spent = $block->getTimeSpentOnObject( $usertime->getObjectPHID(), PhabricatorTime::getNow()); $time_spent = $time_spent == 0 ? 'none' : phutil_format_relative_time_detailed($time_spent); if ($usertime->getDateEnded() !== null) { $item->addAttribute( pht( 'Tracked %s', $time_spent)); $item->addAttribute( pht( 'Ended on %s', phabricator_datetime($usertime->getDateEnded(), $viewer))); } else { $item->addAttribute( pht( 'Tracked %s so far', $time_spent)); if ($usertime->getObjectPHID() !== null && $usertime->getUserPHID() === $viewer->getPHID()) { $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-stop') ->addSigil('phrequent-stop-tracking') ->setWorkflow(true) ->setRenderNameAsTooltip(true) ->setName(pht('Stop')) ->setHref( '/phrequent/track/stop/'. $usertime->getObjectPHID().'/')); } $item->setStatusIcon('fa-clock-o green'); } $view->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($view); return $result; } } diff --git a/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php b/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php index f2e2c99399..8814b25b9c 100644 --- a/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php +++ b/src/applications/phurl/query/PhabricatorPhurlURLSearchEngine.php @@ -1,147 +1,147 @@ setLabel(pht('Created By')) ->setKey('authorPHIDs') ->setDatasource(new PhabricatorPeopleUserFunctionDatasource()), id(new PhabricatorSearchTextField()) ->setLabel(pht('Name Contains')) ->setKey('name') ->setDescription(pht('Search for Phurl URLs by name substring.')), id(new PhabricatorSearchStringListField()) ->setLabel(pht('Aliases')) ->setKey('aliases') ->setDescription(pht('Search for Phurl URLs by alias.')), id(new PhabricatorSearchStringListField()) ->setLabel(pht('Long URLs')) ->setKey('longurls') ->setDescription( pht('Search for Phurl URLs by the non-shortened URL.')), ); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } if ($map['name'] !== null) { $query->withNameNgrams($map['name']); } if ($map['aliases']) { $query->withAliases($map['aliases']); } if ($map['longurls']) { $query->withLongURLs($map['longurls']); } return $query; } protected function getURI($path) { return '/phurl/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All URLs'), 'authored' => pht('Authored'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); switch ($query_key) { case 'authored': return $query->setParameter('authorPHIDs', array($viewer->getPHID())); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $urls, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($urls, 'PhabricatorPhurlURL'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $handles = $viewer->loadHandles(mpull($urls, 'getAuthorPHID')); foreach ($urls as $url) { $name = $url->getName(); $item = id(new PHUIObjectItemView()) ->setUser($viewer) ->setObject($url) ->setObjectName('U'.$url->getID()) ->setHeader($name) ->setHref('/U'.$url->getID()) ->addAttribute($url->getAlias()) ->addAttribute($url->getLongURL()); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No URLs found.')); return $result; } protected function getNewUserBody() { $create_uri = id(new PhabricatorPhurlURLEditEngine()) ->getEditURI(); $create_button = id(new PHUIButtonView()) ->setTag('a') ->setText(pht('Shorten a URL')) ->setHref($create_uri) ->setColor(PHUIButtonView::GREEN); $icon = $this->getApplication()->getIcon(); $app_name = $this->getApplication()->getName(); $view = id(new PHUIBigInfoView()) ->setIcon($icon) ->setTitle(pht('Welcome to %s', $app_name)) ->setDescription( pht('Create reusable, memorable, shorter URLs for easy accessibility.')) ->addAction($create_button); return $view; } } diff --git a/src/applications/project/query/PhabricatorProjectColumnSearchEngine.php b/src/applications/project/query/PhabricatorProjectColumnSearchEngine.php index 0658ec75b0..68fe1e7eb0 100644 --- a/src/applications/project/query/PhabricatorProjectColumnSearchEngine.php +++ b/src/applications/project/query/PhabricatorProjectColumnSearchEngine.php @@ -1,75 +1,78 @@ setLabel(pht('Projects')) ->setKey('projectPHIDs') ->setConduitKey('projects') ->setAliases(array('project', 'projects', 'projectPHID')), ); } - protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['projectPHIDs']) { $query->withProjectPHIDs($map['projectPHIDs']); } return $query; } protected function getURI($path) { // NOTE: There's no way to query columns in the web UI, at least for // the moment. return null; } protected function getBuiltinQueryNames() { $names = array(); $names['all'] = pht('All'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $projects, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($projects, 'PhabricatorProjectColumn'); $viewer = $this->requireViewer(); return null; } } diff --git a/src/applications/releeph/query/ReleephBranchSearchEngine.php b/src/applications/releeph/query/ReleephBranchSearchEngine.php index 68ec126eb5..441f70e992 100644 --- a/src/applications/releeph/query/ReleephBranchSearchEngine.php +++ b/src/applications/releeph/query/ReleephBranchSearchEngine.php @@ -1,196 +1,200 @@ product = $product; return $this; } public function getProduct() { return $this->product; } public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); $saved->setParameter('active', $request->getStr('active')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new ReleephBranchQuery()) ->needCutPointCommits(true) ->withProductPHIDs(array($this->getProduct()->getPHID())); $active = $saved->getParameter('active'); $value = idx($this->getActiveValues(), $active); if ($value !== null) { $query->withStatus($value); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $form->appendChild( id(new AphrontFormSelectControl()) ->setName('active') ->setLabel(pht('Show Branches')) ->setValue($saved_query->getParameter('active')) ->setOptions($this->getActiveOptions())); } protected function getURI($path) { return '/releeph/product/'.$this->getProduct()->getID().'/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'open' => pht('Open'), 'all' => pht('All'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'open': return $query ->setParameter('active', 'open'); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } private function getActiveOptions() { return array( 'open' => pht('Open Branches'), 'all' => pht('Open and Closed Branches'), ); } private function getActiveValues() { return array( 'open' => ReleephBranchQuery::STATUS_OPEN, 'all' => ReleephBranchQuery::STATUS_ALL, ); } protected function renderResultList( array $branches, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($branches, 'ReleephBranch'); $viewer = $this->getRequest()->getUser(); $products = mpull($branches, 'getProduct'); $repo_phids = mpull($products, 'getRepositoryPHID'); if ($repo_phids) { $repos = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->withPHIDs($repo_phids) ->execute(); $repos = mpull($repos, null, 'getPHID'); } else { $repos = array(); } $requests = array(); if ($branches) { $requests = id(new ReleephRequestQuery()) ->setViewer($viewer) ->withBranchIDs(mpull($branches, 'getID')) ->withStatus(ReleephRequestQuery::STATUS_OPEN) ->execute(); $requests = mgroup($requests, 'getBranchID'); } $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($branches as $branch) { $diffusion_href = null; $repo = idx($repos, $branch->getProduct()->getRepositoryPHID()); if ($repo) { $drequest = DiffusionRequest::newFromDictionary( array( 'user' => $viewer, 'repository' => $repo, )); $diffusion_href = $drequest->generateURI( array( 'action' => 'branch', 'branch' => $branch->getName(), )); } $branch_link = $branch->getName(); if ($diffusion_href) { $branch_link = phutil_tag( 'a', array( 'href' => $diffusion_href, ), $branch_link); } $item = id(new PHUIObjectItemView()) ->setHeader($branch->getDisplayName()) ->setHref($this->getApplicationURI('branch/'.$branch->getID().'/')) ->addAttribute($branch_link); if (!$branch->getIsActive()) { $item->setDisabled(true); } $commit = $branch->getCutPointCommit(); if ($commit) { $item->addIcon( 'none', phabricator_datetime($commit->getEpoch(), $viewer)); } $open_count = count(idx($requests, $branch->getID(), array())); if ($open_count) { $item->setStatusIcon('fa-code-fork orange'); $item->addIcon( 'fa-code-fork', pht( '%s Open Pull Request(s)', new PhutilNumber($open_count))); } $list->addItem($item); } return id(new PhabricatorApplicationSearchResultView()) ->setObjectList($list); } } diff --git a/src/applications/releeph/query/ReleephProductSearchEngine.php b/src/applications/releeph/query/ReleephProductSearchEngine.php index f56125a687..d58ee735f1 100644 --- a/src/applications/releeph/query/ReleephProductSearchEngine.php +++ b/src/applications/releeph/query/ReleephProductSearchEngine.php @@ -1,130 +1,134 @@ setParameter('active', $request->getStr('active')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new ReleephProductQuery()) ->setOrder(ReleephProductQuery::ORDER_NAME); $active = $saved->getParameter('active'); $value = idx($this->getActiveValues(), $active); if ($value !== null) { $query->withActive($value); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $form->appendChild( id(new AphrontFormSelectControl()) ->setName('active') ->setLabel(pht('Show Products')) ->setValue($saved_query->getParameter('active')) ->setOptions($this->getActiveOptions())); } protected function getURI($path) { return '/releeph/project/'.$path; } protected function getBuiltinQueryNames() { return array( 'active' => pht('Active'), 'all' => pht('All'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'active': return $query ->setParameter('active', 'active'); case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } private function getActiveOptions() { return array( 'all' => pht('Active and Inactive Products'), 'active' => pht('Active Products'), 'inactive' => pht('Inactive Products'), ); } private function getActiveValues() { return array( 'all' => null, 'active' => 1, 'inactive' => 0, ); } protected function renderResultList( array $products, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($products, 'ReleephProject'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($products as $product) { $id = $product->getID(); $item = id(new PHUIObjectItemView()) ->setHeader($product->getName()) ->setHref($this->getApplicationURI("product/{$id}/")); if (!$product->getIsActive()) { $item->setDisabled(true); $item->addIcon('none', pht('Inactive')); } $repo = $product->getRepository(); $item->addAttribute( phutil_tag( 'a', array( 'href' => $repo->getURI(), ), $repo->getMonogram())); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); return $result; } } diff --git a/src/applications/releeph/query/ReleephRequestSearchEngine.php b/src/applications/releeph/query/ReleephRequestSearchEngine.php index 20aaa38ed9..7f866405c1 100644 --- a/src/applications/releeph/query/ReleephRequestSearchEngine.php +++ b/src/applications/releeph/query/ReleephRequestSearchEngine.php @@ -1,221 +1,225 @@ branch = $branch; return $this; } public function getBranch() { return $this->branch; } public function setBaseURI($base_uri) { $this->baseURI = $base_uri; return $this; } public function buildSavedQueryFromRequest(AphrontRequest $request) { $saved = new PhabricatorSavedQuery(); $saved->setParameter('status', $request->getStr('status')); $saved->setParameter('severity', $request->getStr('severity')); $saved->setParameter( 'requestorPHIDs', $this->readUsersFromRequest($request, 'requestors')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new ReleephRequestQuery()) ->withBranchIDs(array($this->getBranch()->getID())); $status = $saved->getParameter('status'); $status = idx($this->getStatusValues(), $status); if ($status) { $query->withStatus($status); } $severity = $saved->getParameter('severity'); if ($severity) { $query->withSeverities(array($severity)); } $requestor_phids = $saved->getParameter('requestorPHIDs'); if ($requestor_phids) { $query->withRequestorPHIDs($requestor_phids); } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $requestor_phids = $saved_query->getParameter('requestorPHIDs', array()); $form ->appendChild( id(new AphrontFormSelectControl()) ->setName('status') ->setLabel(pht('Status')) ->setValue($saved_query->getParameter('status')) ->setOptions($this->getStatusOptions())) ->appendChild( id(new AphrontFormSelectControl()) ->setName('severity') ->setLabel(pht('Severity')) ->setValue($saved_query->getParameter('severity')) ->setOptions($this->getSeverityOptions())) ->appendControl( id(new AphrontFormTokenizerControl()) ->setDatasource(new PhabricatorPeopleDatasource()) ->setName('requestors') ->setLabel(pht('Requestors')) ->setValue($requestor_phids)); } protected function getURI($path) { return $this->baseURI.$path; } protected function getBuiltinQueryNames() { $names = array( 'open' => pht('Open Requests'), 'all' => pht('All Requests'), ); if ($this->requireViewer()->isLoggedIn()) { $names['requested'] = pht('Requested'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'open': return $query->setParameter('status', 'open'); case 'all': return $query; case 'requested': return $query->setParameter( 'requestorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } private function getStatusOptions() { return array( '' => pht('(All Requests)'), 'open' => pht('Open Requests'), 'requested' => pht('Pull Requested'), 'needs-pull' => pht('Needs Pull'), 'rejected' => pht('Rejected'), 'abandoned' => pht('Abandoned'), 'pulled' => pht('Pulled'), 'needs-revert' => pht('Needs Revert'), 'reverted' => pht('Reverted'), ); } private function getStatusValues() { return array( 'open' => ReleephRequestQuery::STATUS_OPEN, 'requested' => ReleephRequestQuery::STATUS_REQUESTED, 'needs-pull' => ReleephRequestQuery::STATUS_NEEDS_PULL, 'rejected' => ReleephRequestQuery::STATUS_REJECTED, 'abandoned' => ReleephRequestQuery::STATUS_ABANDONED, 'pulled' => ReleephRequestQuery::STATUS_PULLED, 'needs-revert' => ReleephRequestQuery::STATUS_NEEDS_REVERT, 'reverted' => ReleephRequestQuery::STATUS_REVERTED, ); } private function getSeverityOptions() { if (ReleephDefaultFieldSelector::isFacebook()) { return array( '' => pht('(All Severities)'), 11 => pht('HOTFIX'), 12 => pht('PIGGYBACK'), 13 => pht('RELEASE'), 14 => pht('DAILY'), 15 => pht('PARKING'), ); } else { return array( '' => pht('(All Severities)'), ReleephSeverityFieldSpecification::HOTFIX => pht('Hotfix'), ReleephSeverityFieldSpecification::RELEASE => pht('Release'), ); } } protected function renderResultList( array $requests, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($requests, 'ReleephRequest'); $viewer = $this->requireViewer(); // TODO: This is generally a bit sketchy, but we don't do this kind of // thing elsewhere at the moment. For the moment it shouldn't be hugely // costly, and we can batch things later. Generally, this commits fewer // sins than the old code did. $engine = id(new PhabricatorMarkupEngine()) ->setViewer($viewer); $list = array(); foreach ($requests as $pull) { $field_list = PhabricatorCustomField::getObjectFields( $pull, PhabricatorCustomField::ROLE_VIEW); $field_list ->setViewer($viewer) ->readFieldsFromStorage($pull); foreach ($field_list->getFields() as $field) { if ($field->shouldMarkup()) { $field->setMarkupEngine($engine); } } $list[] = id(new ReleephRequestView()) ->setUser($viewer) ->setCustomFields($field_list) ->setPullRequest($pull) ->setIsListView(true); } // This is quite sketchy, but the list has not actually rendered yet, so // this still allows us to batch the markup rendering. $engine->process(); return id(new PhabricatorApplicationSearchResultView()) ->setContent($list); } } diff --git a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php index 835e483cff..cf7dc0f6ba 100644 --- a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php +++ b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php @@ -1,283 +1,287 @@ setParameter('query', $request->getStr('query')); $saved->setParameter( 'statuses', $this->readListFromRequest($request, 'statuses')); $saved->setParameter( 'types', $this->readListFromRequest($request, 'types')); $saved->setParameter( 'authorPHIDs', $this->readUsersFromRequest($request, 'authorPHIDs')); $saved->setParameter( 'ownerPHIDs', $this->readUsersFromRequest($request, 'ownerPHIDs')); $saved->setParameter( 'subscriberPHIDs', $this->readSubscribersFromRequest($request, 'subscriberPHIDs')); $saved->setParameter( 'projectPHIDs', $this->readPHIDsFromRequest($request, 'projectPHIDs')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = new PhabricatorSearchDocumentQuery(); // Convert the saved query into a resolved form (without typeahead // functions) which the fulltext search engines can execute. $config = clone $saved; $viewer = $this->requireViewer(); $datasource = id(new PhabricatorPeopleOwnerDatasource()) ->setViewer($viewer); $owner_phids = $this->readOwnerPHIDs($config); $owner_phids = $datasource->evaluateTokens($owner_phids); foreach ($owner_phids as $key => $phid) { if ($phid == PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN) { $config->setParameter('withUnowned', true); unset($owner_phids[$key]); } if ($phid == PhabricatorPeopleAnyOwnerDatasource::FUNCTION_TOKEN) { $config->setParameter('withAnyOwner', true); unset($owner_phids[$key]); } } $config->setParameter('ownerPHIDs', $owner_phids); $datasource = id(new PhabricatorPeopleUserFunctionDatasource()) ->setViewer($viewer); $author_phids = $config->getParameter('authorPHIDs', array()); $author_phids = $datasource->evaluateTokens($author_phids); $config->setParameter('authorPHIDs', $author_phids); $datasource = id(new PhabricatorMetaMTAMailableFunctionDatasource()) ->setViewer($viewer); $subscriber_phids = $config->getParameter('subscriberPHIDs', array()); $subscriber_phids = $datasource->evaluateTokens($subscriber_phids); $config->setParameter('subscriberPHIDs', $subscriber_phids); $query->withSavedQuery($config); return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved) { $options = array(); $author_value = null; $owner_value = null; $subscribers_value = null; $project_value = null; $author_phids = $saved->getParameter('authorPHIDs', array()); $owner_phids = $this->readOwnerPHIDs($saved); $subscriber_phids = $saved->getParameter('subscriberPHIDs', array()); $project_phids = $saved->getParameter('projectPHIDs', array()); $status_values = $saved->getParameter('statuses', array()); $status_values = array_fuse($status_values); $statuses = array( PhabricatorSearchRelationship::RELATIONSHIP_OPEN => pht('Open'), PhabricatorSearchRelationship::RELATIONSHIP_CLOSED => pht('Closed'), ); $status_control = id(new AphrontFormCheckboxControl()) ->setLabel(pht('Document Status')); foreach ($statuses as $status => $name) { $status_control->addCheckbox( 'statuses[]', $status, $name, isset($status_values[$status])); } $type_values = $saved->getParameter('types', array()); $type_values = array_fuse($type_values); $types_control = id(new AphrontFormTokenizerControl()) ->setLabel(pht('Document Types')) ->setName('types') ->setDatasource(new PhabricatorSearchDocumentTypeDatasource()) ->setValue($type_values); $form ->appendChild( phutil_tag( 'input', array( 'type' => 'hidden', 'name' => 'jump', 'value' => 'no', ))) ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Query')) ->setName('query') ->setValue($saved->getParameter('query'))) ->appendChild($status_control) ->appendControl($types_control) ->appendControl( id(new AphrontFormTokenizerControl()) ->setName('authorPHIDs') ->setLabel(pht('Authors')) ->setDatasource(new PhabricatorPeopleUserFunctionDatasource()) ->setValue($author_phids)) ->appendControl( id(new AphrontFormTokenizerControl()) ->setName('ownerPHIDs') ->setLabel(pht('Owners')) ->setDatasource(new PhabricatorPeopleOwnerDatasource()) ->setValue($owner_phids)) ->appendControl( id(new AphrontFormTokenizerControl()) ->setName('subscriberPHIDs') ->setLabel(pht('Subscribers')) ->setDatasource(new PhabricatorMetaMTAMailableFunctionDatasource()) ->setValue($subscriber_phids)) ->appendControl( id(new AphrontFormTokenizerControl()) ->setName('projectPHIDs') ->setLabel(pht('Tags')) ->setDatasource(new PhabricatorProjectDatasource()) ->setValue($project_phids)); } protected function getURI($path) { return '/search/'.$path; } protected function getBuiltinQueryNames() { return array( 'all' => pht('All Documents'), 'open' => pht('Open Documents'), 'open-tasks' => pht('Open Tasks'), ); } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter('statuses', array('open')); case 'open-tasks': return $query ->setParameter('statuses', array('open')) ->setParameter('types', array(ManiphestTaskPHIDType::TYPECONST)); } return parent::buildSavedQueryFromBuiltin($query_key); } public static function getIndexableDocumentTypes( PhabricatorUser $viewer = null) { // TODO: This is inelegant and not very efficient, but gets us reasonable // results. It would be nice to do this more elegantly. $objects = id(new PhutilClassMapQuery()) ->setAncestorClass('PhabricatorFulltextInterface') ->execute(); $type_map = array(); foreach ($objects as $object) { $phid_type = phid_get_type($object->generatePHID()); $type_map[$phid_type] = $object; } if ($viewer) { $types = PhabricatorPHIDType::getAllInstalledTypes($viewer); } else { $types = PhabricatorPHIDType::getAllTypes(); } $results = array(); foreach ($types as $type) { $typeconst = $type->getTypeConstant(); $object = idx($type_map, $typeconst); if ($object) { $results[$typeconst] = $type->getTypeName(); } } asort($results); return $results; } public function shouldUseOffsetPaging() { return true; } protected function renderResultList( array $results, PhabricatorSavedQuery $query, array $handles) { $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); $list->setNoDataString(pht('No results found.')); if ($results) { $objects = id(new PhabricatorObjectQuery()) ->setViewer($viewer) ->withPHIDs(mpull($results, 'getPHID')) ->execute(); foreach ($results as $phid => $handle) { $view = id(new PhabricatorSearchResultView()) ->setHandle($handle) ->setQuery($query) ->setObject(idx($objects, $phid)) ->render(); $list->addItem($view); } } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); return $result; } private function readOwnerPHIDs(PhabricatorSavedQuery $saved) { $owner_phids = $saved->getParameter('ownerPHIDs', array()); // This was an old checkbox from before typeahead functions. if ($saved->getParameter('withUnowned')) { $owner_phids[] = PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN; } return $owner_phids; } } diff --git a/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php b/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php index 70cd4cd1a3..4ba1a0e879 100644 --- a/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php +++ b/src/applications/transactions/query/PhabricatorEditEngineSearchEngine.php @@ -1,87 +1,91 @@ newQuery(); return $query; } protected function buildCustomSearchFields() { return array(); } protected function getDefaultFieldOrder() { return array(); } protected function getURI($path) { return '/transactions/editengine/'.$path; } protected function getBuiltinQueryNames() { $names = array( 'all' => pht('All Edit Engines'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $engines, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($engines, 'PhabricatorEditEngine'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($engines as $engine) { if (!$engine->isEngineConfigurable()) { continue; } $engine_key = $engine->getEngineKey(); $query_uri = "/transactions/editengine/{$engine_key}/"; $application = $engine->getApplication(); $app_icon = $application->getIcon(); $item = id(new PHUIObjectItemView()) ->setHeader($engine->getSummaryHeader()) ->setHref($query_uri) ->setStatusIcon($app_icon) ->addAttribute($engine->getSummaryText()); $list->addItem($item); } return id(new PhabricatorApplicationSearchResultView()) ->setObjectList($list); } } diff --git a/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php b/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php index 223db0e95a..3b9d6c9d48 100644 --- a/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php +++ b/src/infrastructure/daemon/workers/query/PhabricatorWorkerBulkJobSearchEngine.php @@ -1,97 +1,101 @@ newQuery(); if ($map['authorPHIDs']) { $query->withAuthorPHIDs($map['authorPHIDs']); } return $query; } protected function buildCustomSearchFields() { return array( id(new PhabricatorUsersSearchField()) ->setLabel(pht('Authors')) ->setKey('authorPHIDs') ->setAliases(array('author', 'authors')), ); } protected function getURI($path) { return '/daemon/bulk/'.$path; } protected function getBuiltinQueryNames() { $names = array(); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored Jobs'); } $names['all'] = pht('All Jobs'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function renderResultList( array $jobs, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($jobs, 'PhabricatorWorkerBulkJob'); $viewer = $this->requireViewer(); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); foreach ($jobs as $job) { $size = pht('%s Bulk Task(s)', new PhutilNumber($job->getSize())); $item = id(new PHUIObjectItemView()) ->setObjectName(pht('Bulk Job %d', $job->getID())) ->setHeader($job->getJobName()) ->addAttribute(phabricator_datetime($job->getDateCreated(), $viewer)) ->setHref($job->getManageURI()) ->addIcon($job->getStatusIcon(), $job->getStatusName()) ->addIcon('none', $size); $list->addItem($item); } return id(new PhabricatorApplicationSearchResultView()) ->setContent($list); } }