From d30f43b15bb8c93c7905ea5668d1d8bc8f96303a Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 7 May 2014 14:56:30 -0700 Subject: [PATCH] Rough skeleton of a "Query" dashboard panel Summary: Ref T4986. This isn't pretty/usable yet (I need to move rendering out of ListController classes and into SearchEngine classes, I think) but does pull the correct results. Test Plan: {F151537} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T4986 Differential Revision: https://secure.phabricator.com/D9007 --- src/__phutil_library_map__.php | 2 + ...abricatorDashboardPanelRenderingEngine.php | 12 ++- .../PhabricatorDashboardPanelTypeQuery.php | 82 +++++++++++++++++++ .../PhabricatorApplicationSearchEngine.php | 39 ++++++++- .../query/PhabricatorSavedQueryQuery.php | 6 +- 5 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index dbcb00ea2b..efdfefc676 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1463,6 +1463,7 @@ phutil_register_library_map(array( 'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php', 'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php', 'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php', + 'PhabricatorDashboardPanelTypeQuery' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php', 'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php', 'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php', 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', @@ -4306,6 +4307,7 @@ phutil_register_library_map(array( 'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorDashboardPanelType' => 'Phobject', + 'PhabricatorDashboardPanelTypeQuery' => 'PhabricatorDashboardPanelType', 'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType', 'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController', 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', diff --git a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php index 7f83155b17..f7065a7a30 100644 --- a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php +++ b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php @@ -50,8 +50,16 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject { } } - - return $panel_type->renderPanel($viewer, $panel); + try { + return $panel_type->renderPanel($viewer, $panel); + } catch (Exception $ex) { + return $this->renderErrorPanel( + $panel->getName(), + pht( + '%s: %s', + phutil_tag('strong', array(), get_class($ex)), + $ex->getMessage())); + } } private function renderErrorPanel($title, $body) { diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php new file mode 100644 index 0000000000..8cbddd436e --- /dev/null +++ b/src/applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php @@ -0,0 +1,82 @@ + array( + 'name' => pht('ApplicationSearch Class'), + 'type' => 'text', + ), + 'key' => array( + 'name' => pht('ApplicationSearch Key'), + 'type' => 'text', + ), + ); + } + + protected function renderPanelContent( + PhabricatorUser $viewer, + PhabricatorDashboardPanel $panel) { + + $class = $panel->getProperty('class'); + + $engine = PhabricatorApplicationSearchEngine::getEngineByClassName($class); + if (!$engine) { + throw new Exception( + pht( + 'The application search engine "%s" is not known to Phabricator!', + $class)); + } + + $engine->setViewer($viewer); + + $key = $panel->getProperty('key'); + if ($engine->isBuiltinQuery($key)) { + $saved = $engine->buildSavedQueryFromBuiltin($key); + } else { + $saved = id(new PhabricatorSavedQueryQuery()) + ->setViewer($viewer) + ->withEngineClassNames(array($class)) + ->withQueryKeys(array($key)) + ->executeOne(); + } + + if (!$saved) { + throw new Exception( + pht( + 'Query "%s" is unknown to application search engine "%s"!', + $key, + $class)); + } + + $query = $engine->buildQueryFromSavedQuery($saved); + + $results = $query + ->setViewer($viewer) + ->execute(); + + $out = array(); + foreach ($results as $result) { + $out[] = phutil_tag('div', array(), $result->getPHID()); + } + + return $out; + } + +} diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php index 481d5c7737..9f0ecdcdb0 100644 --- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php +++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php @@ -4,10 +4,11 @@ * Represents an abstract search engine for an application. It supports * creating and storing saved queries. * - * @task builtin Builtin Queries - * @task uri Query URIs - * @task dates Date Filters - * @task read Reading Utilities + * @task construct Constructing Engines + * @task builtin Builtin Queries + * @task uri Query URIs + * @task dates Date Filters + * @task read Reading Utilities * * @group search */ @@ -174,6 +175,36 @@ abstract class PhabricatorApplicationSearchEngine { } +/* -( Constructing Engines )----------------------------------------------- */ + + + /** + * Load all available application search engines. + * + * @return list All available engines. + * @task construct + */ + public static function getAllEngines() { + $engines = id(new PhutilSymbolLoader()) + ->setAncestorClass(__CLASS__) + ->loadObjects(); + + return $engines; + } + + + /** + * Get an engine by class name, if it exists. + * + * @return PhabricatorApplicationSearchEngine|null Engine, or null if it does + * not exist. + * @task construct + */ + public static function getEngineByClassName($class_name) { + return idx(self::getAllEngines(), $class_name); + } + + /* -( Builtin Queries )---------------------------------------------------- */ diff --git a/src/applications/search/query/PhabricatorSavedQueryQuery.php b/src/applications/search/query/PhabricatorSavedQueryQuery.php index 70773908a8..7431d6abee 100644 --- a/src/applications/search/query/PhabricatorSavedQueryQuery.php +++ b/src/applications/search/query/PhabricatorSavedQueryQuery.php @@ -40,21 +40,21 @@ final class PhabricatorSavedQueryQuery private function buildWhereClause($conn_r) { $where = array(); - if ($this->ids) { + if ($this->ids !== null) { $where[] = qsprintf( $conn_r, 'id IN (%Ld)', $this->ids); } - if ($this->engineClassNames) { + if ($this->engineClassNames !== null) { $where[] = qsprintf( $conn_r, 'engineClassName IN (%Ls)', $this->engineClassNames); } - if ($this->queryKeys) { + if ($this->queryKeys !== null) { $where[] = qsprintf( $conn_r, 'queryKey IN (%Ls)',