From 42af0d66d9ec561dfd8eefc6f9a57679c3c6104f Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 5 Aug 2013 14:10:41 -0700 Subject: [PATCH] Use ApplicationSearch in Feed Summary: Ref T2625. This doesn't do anything fancy, but gives feed a little more flexibility. Test Plan: Viewed `/feed/`. Reviewers: btrahan, chad Reviewed By: chad CC: aran Maniphest Tasks: T2625 Differential Revision: https://secure.phabricator.com/D6681 --- src/__phutil_library_map__.php | 12 +- .../PhabricatorApplicationFeed.php | 2 +- .../controller/PhabricatorFeedController.php | 10 +- .../PhabricatorFeedListController.php | 39 ++++++ .../PhabricatorFeedMainController.php | 89 ------------ .../feed/{ => query}/PhabricatorFeedQuery.php | 0 .../query/PhabricatorFeedSearchEngine.php | 128 ++++++++++++++++++ 7 files changed, 184 insertions(+), 96 deletions(-) create mode 100644 src/applications/feed/controller/PhabricatorFeedListController.php delete mode 100644 src/applications/feed/controller/PhabricatorFeedMainController.php rename src/applications/feed/{ => query}/PhabricatorFeedQuery.php (100%) create mode 100644 src/applications/feed/query/PhabricatorFeedSearchEngine.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index d6ea568921..9155ea4a8e 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1117,11 +1117,12 @@ phutil_register_library_map(array( 'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php', 'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php', 'PhabricatorFeedDetailController' => 'applications/feed/controller/PhabricatorFeedDetailController.php', - 'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php', + 'PhabricatorFeedListController' => 'applications/feed/controller/PhabricatorFeedListController.php', 'PhabricatorFeedManagementRepublishWorkflow' => 'applications/feed/management/PhabricatorFeedManagementRepublishWorkflow.php', 'PhabricatorFeedManagementWorkflow' => 'applications/feed/management/PhabricatorFeedManagementWorkflow.php', 'PhabricatorFeedPublicStreamController' => 'applications/feed/controller/PhabricatorFeedPublicStreamController.php', - 'PhabricatorFeedQuery' => 'applications/feed/PhabricatorFeedQuery.php', + 'PhabricatorFeedQuery' => 'applications/feed/query/PhabricatorFeedQuery.php', + 'PhabricatorFeedSearchEngine' => 'applications/feed/query/PhabricatorFeedSearchEngine.php', 'PhabricatorFeedStory' => 'applications/feed/story/PhabricatorFeedStory.php', 'PhabricatorFeedStoryAggregate' => 'applications/feed/story/PhabricatorFeedStoryAggregate.php', 'PhabricatorFeedStoryAudit' => 'applications/feed/story/PhabricatorFeedStoryAudit.php', @@ -3159,11 +3160,16 @@ phutil_register_library_map(array( 'PhabricatorFeedController' => 'PhabricatorController', 'PhabricatorFeedDAO' => 'PhabricatorLiskDAO', 'PhabricatorFeedDetailController' => 'PhabricatorFeedController', - 'PhabricatorFeedMainController' => 'PhabricatorFeedController', + 'PhabricatorFeedListController' => + array( + 0 => 'PhabricatorFeedController', + 1 => 'PhabricatorApplicationSearchResultsControllerInterface', + ), 'PhabricatorFeedManagementRepublishWorkflow' => 'PhabricatorFeedManagementWorkflow', 'PhabricatorFeedManagementWorkflow' => 'PhutilArgumentWorkflow', 'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController', 'PhabricatorFeedQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorFeedSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorFeedStory' => 'PhabricatorPolicyInterface', 'PhabricatorFeedStoryAggregate' => 'PhabricatorFeedStory', 'PhabricatorFeedStoryAudit' => 'PhabricatorFeedStory', diff --git a/src/applications/feed/application/PhabricatorApplicationFeed.php b/src/applications/feed/application/PhabricatorApplicationFeed.php index 193fdd5db3..4055c4af34 100644 --- a/src/applications/feed/application/PhabricatorApplicationFeed.php +++ b/src/applications/feed/application/PhabricatorApplicationFeed.php @@ -23,7 +23,7 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication { '/feed/' => array( 'public/' => 'PhabricatorFeedPublicStreamController', '(?P\d+)/' => 'PhabricatorFeedDetailController', - '(?:(?P[^/]+)/)?' => 'PhabricatorFeedMainController', + '(?:query/(?P[^/]+)/)?' => 'PhabricatorFeedListController', ), ); } diff --git a/src/applications/feed/controller/PhabricatorFeedController.php b/src/applications/feed/controller/PhabricatorFeedController.php index 7c0fe830fd..f698af41fb 100644 --- a/src/applications/feed/controller/PhabricatorFeedController.php +++ b/src/applications/feed/controller/PhabricatorFeedController.php @@ -23,12 +23,16 @@ abstract class PhabricatorFeedController extends PhabricatorController { } protected function buildSideNavView() { + $user = $this->getRequest()->getUser(); + $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); - $nav->addLabel(pht('Feed')); - $nav->addFilter('all', pht('All Activity')); - $nav->addFilter('projects', pht('My Projects')); + id(new PhabricatorFeedSearchEngine()) + ->setViewer($user) + ->addNavigationItems($nav->getMenu()); + + $nav->selectFilter(null); return $nav; } diff --git a/src/applications/feed/controller/PhabricatorFeedListController.php b/src/applications/feed/controller/PhabricatorFeedListController.php new file mode 100644 index 0000000000..b5aac9901c --- /dev/null +++ b/src/applications/feed/controller/PhabricatorFeedListController.php @@ -0,0 +1,39 @@ +queryKey = idx($data, 'queryKey'); + } + + public function processRequest() { + $request = $this->getRequest(); + $controller = id(new PhabricatorApplicationSearchController($request)) + ->setQueryKey($this->queryKey) + ->setSearchEngine(new PhabricatorFeedSearchEngine()) + ->setNavigation($this->buildSideNavView()); + + return $this->delegateToController($controller); + } + + public function renderResultsList( + array $feed, + PhabricatorSavedQuery $query) { + + $builder = new PhabricatorFeedBuilder($feed); + $builder->setUser($this->getRequest()->getUser()); + $view = $builder->buildView(); + + return hsprintf( + '
%s
', + $view); + } + +} diff --git a/src/applications/feed/controller/PhabricatorFeedMainController.php b/src/applications/feed/controller/PhabricatorFeedMainController.php deleted file mode 100644 index 556462ee3d..0000000000 --- a/src/applications/feed/controller/PhabricatorFeedMainController.php +++ /dev/null @@ -1,89 +0,0 @@ -filter = idx($data, 'filter'); - } - - public function processRequest() { - $request = $this->getRequest(); - $user = $request->getUser(); - - $nav = $this->buildSideNavView(); - $filter = $nav->selectFilter($this->filter, 'all'); - - $pager = new AphrontCursorPagerView(); - $pager->readFromRequest($request); - $pager->setPageSize(200); - - - $query = id(new PhabricatorFeedQuery()) - ->setViewer($user); - - $nodata = null; - switch ($filter) { - case 'all': - $title = pht('Feed'); - break; - case 'projects': - $projects = id(new PhabricatorProjectQuery()) - ->setViewer($user) - ->withMemberPHIDs(array($user->getPHID())) - ->execute(); - - if (!$projects) { - $nodata = pht('You have not joined any projects.'); - } else { - $query->setFilterPHIDs(mpull($projects, 'getPHID')); - } - - $title = pht('Feed: My Projects'); - break; - } - - if ($nodata) { - $feed_view = id(new AphrontErrorView()) - ->setSeverity(AphrontErrorView::SEVERITY_NODATA) - ->setTitle(pht('No Stories')) - ->appendChild($nodata); - } else { - $feed = $query->executeWithCursorPager($pager); - - $builder = new PhabricatorFeedBuilder($feed); - $builder->setUser($user); - $feed_view = $builder->buildView(); - } - - $feed_view = hsprintf( - '
%s
', - $feed_view); - - $crumbs = $this - ->buildApplicationCrumbs($nav) - ->addCrumb( - id(new PhabricatorCrumbView()) - ->setName($title) - ->setHref($this->getApplicationURI('filter/'.$filter.'/'))); - - $nav->setCrumbs($crumbs); - - - $nav->appendChild( - array( - $feed_view, - $pager, - )); - - return $this->buildApplicationPage( - $nav, - array( - 'title' => $title, - 'device' => true, - 'dust' => true, - )); - } - -} diff --git a/src/applications/feed/PhabricatorFeedQuery.php b/src/applications/feed/query/PhabricatorFeedQuery.php similarity index 100% rename from src/applications/feed/PhabricatorFeedQuery.php rename to src/applications/feed/query/PhabricatorFeedQuery.php diff --git a/src/applications/feed/query/PhabricatorFeedSearchEngine.php b/src/applications/feed/query/PhabricatorFeedSearchEngine.php new file mode 100644 index 0000000000..e012fc0e01 --- /dev/null +++ b/src/applications/feed/query/PhabricatorFeedSearchEngine.php @@ -0,0 +1,128 @@ +setParameter( + 'userPHIDs', + array_values($request->getArr('userPHIDs'))); + + $saved->setParameter( + 'projectPHIDs', + array_values($request->getArr('projectPHIDs'))); + + $saved->setParameter( + 'viewerProjects', + $request->getBool('viewerProjects')); + + return $saved; + } + + public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { + $query = id(new PhabricatorFeedQuery()); + + $phids = array(); + + $user_phids = $saved->getParameter('userPHIDs'); + if ($user_phids) { + $phids[] = $user_phids; + } + + $proj_phids = $saved->getParameter('projectPHIDs'); + if ($proj_phids) { + $phids[] = $proj_phids; + } + + $viewer_projects = $saved->getParameter('viewerProjects'); + if ($viewer_projects) { + $viewer = $this->requireViewer(); + $projects = id(new PhabricatorProjectQuery()) + ->setViewer($viewer) + ->withMemberPHIDs(array($viewer->getPHID())) + ->execute(); + $phids[] = mpull($projects, 'getPHID'); + } + + $phids = array_mergev($phids); + if ($phids) { + $query->setFilterPHIDs($phids); + } + + return $query; + } + + public function buildSearchForm( + AphrontFormView $form, + PhabricatorSavedQuery $saved_query) { + + $user_phids = $saved_query->getParameter('userPHIDs', array()); + $proj_phids = $saved_query->getParameter('projectPHIDs', array()); + + $phids = array_merge($user_phids, $proj_phids); + $handles = id(new PhabricatorHandleQuery()) + ->setViewer($this->requireViewer()) + ->withPHIDs($phids) + ->execute(); + $tokens = mpull($handles, 'getFullName', 'getPHID'); + $user_tokens = array_select_keys($tokens, $user_phids); + $proj_tokens = array_select_keys($tokens, $proj_phids); + + $viewer_projects = $saved_query->getParameter('viewerProjects'); + + $form + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/users/') + ->setName('userPHIDs') + ->setLabel(pht('Include Users')) + ->setValue($user_tokens)) + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/projects/') + ->setName('projectPHIDs') + ->setLabel(pht('Include Projects')) + ->setValue($proj_tokens)) + ->appendChild( + id(new AphrontFormCheckboxControl()) + ->addCheckbox( + 'viewerProjects', + 1, + pht('Include stories about projects I am a member of.'), + $viewer_projects)); + } + + protected function getURI($path) { + return '/feed/'.$path; + } + + public function getBuiltinQueryNames() { + $names = array( + 'all' => pht('All Stories'), + ); + + if ($this->requireViewer()->isLoggedIn()) { + $names['projects'] = pht('Projects'); + } + + return $names; + } + + public function buildSavedQueryFromBuiltin($query_key) { + + $query = $this->newSavedQuery(); + $query->setQueryKey($query_key); + + switch ($query_key) { + case 'all': + return $query; + case 'projects': + return $query->setParameter('viewerProjects', true); + } + + return parent::buildSavedQueryFromBuiltin($query_key); + } + +}