From fb765b8c93feeb36d00f160e8a34ee0decbf2d92 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 30 May 2013 18:55:04 -0700 Subject: [PATCH] Add language and date ranges to Paste queries Summary: Ref T2625. Ref T3273. This is mostly a UI foil for T3273. Right now, to find tasks without owners or without projects you search for the magic strings "upforgrabs" and "noproject". Unsurprisingly, no users have ever figured this out. I want to get rid of it. Instead, these interfaces will look like: Assigned: [ Type a user name... ] [ X ] Find unassigned tasks. Projects: [ Type a project name... ] [ X ] Find tasks with no projects. Seems reasonable, I think? Test Plan: Searched for "rainbow, js", "rainbow + no language", "no language", date ranges, etc. Reviewers: chad, btrahan Reviewed By: chad CC: aran Maniphest Tasks: T2625, T3273 Differential Revision: https://secure.phabricator.com/D6085 --- resources/sql/patches/20130530.pastekeys.sql | 5 + .../paste/query/PhabricatorPasteQuery.php | 47 ++++++++++ .../query/PhabricatorPasteSearchEngine.php | 93 ++++++++++++------- .../patch/PhabricatorBuiltinPatchList.php | 4 + 4 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 resources/sql/patches/20130530.pastekeys.sql diff --git a/resources/sql/patches/20130530.pastekeys.sql b/resources/sql/patches/20130530.pastekeys.sql new file mode 100644 index 0000000000..4767aa18f8 --- /dev/null +++ b/resources/sql/patches/20130530.pastekeys.sql @@ -0,0 +1,5 @@ +ALTER TABLE {$NAMESPACE}_pastebin.pastebin_paste + ADD KEY `key_dateCreated` (dateCreated); + +ALTER TABLE {$NAMESPACE}_pastebin.pastebin_paste + ADD KEY `key_language` (language); diff --git a/src/applications/paste/query/PhabricatorPasteQuery.php b/src/applications/paste/query/PhabricatorPasteQuery.php index 65794eae94..5c00873e1d 100644 --- a/src/applications/paste/query/PhabricatorPasteQuery.php +++ b/src/applications/paste/query/PhabricatorPasteQuery.php @@ -10,6 +10,10 @@ final class PhabricatorPasteQuery private $needContent; private $needRawContent; + private $languages; + private $includeNoLanguage; + private $dateCreatedAfter; + private $dateCreatedBefore; public function withIDs(array $ids) { $this->ids = $ids; @@ -41,6 +45,28 @@ final class PhabricatorPasteQuery return $this; } + public function withLanguages(array $languages) { + $this->includeNoLanguage = false; + foreach ($languages as $key => $language) { + if ($language === null) { + $languages[$key] = ''; + continue; + } + } + $this->languages = $languages; + return $this; + } + + public function withDateCreatedBefore($date_created_before) { + $this->dateCreatedBefore = $date_created_before; + return $this; + } + + public function withDateCreatedAfter($date_created_after) { + $this->dateCreatedAfter = $date_created_after; + return $this; + } + protected function loadPage() { $table = new PhabricatorPaste(); $conn_r = $table->establishConnection('r'); @@ -107,6 +133,27 @@ final class PhabricatorPasteQuery $this->parentPHIDs); } + if ($this->languages) { + $where[] = qsprintf( + $conn_r, + 'language IN (%Ls)', + $this->languages); + } + + if ($this->dateCreatedAfter) { + $where[] = qsprintf( + $conn_r, + 'dateCreated >= %d', + $this->dateCreatedAfter); + } + + if ($this->dateCreatedBefore) { + $where[] = qsprintf( + $conn_r, + 'dateCreated <= %d', + $this->dateCreatedBefore); + } + return $this->formatWhereClause($where); } diff --git a/src/applications/paste/query/PhabricatorPasteSearchEngine.php b/src/applications/paste/query/PhabricatorPasteSearchEngine.php index efed23a171..36fe6e2c49 100644 --- a/src/applications/paste/query/PhabricatorPasteSearchEngine.php +++ b/src/applications/paste/query/PhabricatorPasteSearchEngine.php @@ -1,51 +1,46 @@ setParameter( 'authorPHIDs', array_values($request->getArr('authors'))); + $languages = $request->getStrList('languages'); + if ($request->getBool('noLanguage')) { + $languages[] = null; + } + $saved->setParameter('languages', $languages); + + $saved->setParameter('createdStart', $request->getStr('createdStart')); + $saved->setParameter('createdEnd', $request->getStr('createdEnd')); + return $saved; } - /** - * Executes the saved query. - * - * @param PhabricatorSavedQuery - * @return The result of the query. - */ public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhabricatorPasteQuery()) ->needContent(true) - ->withIDs($saved->getParameter('ids', array())) - ->withPHIDs($saved->getParameter('phids', array())) ->withAuthorPHIDs($saved->getParameter('authorPHIDs', array())) - ->withParentPHIDs($saved->getParameter('parentPHIDs', array())); + ->withLanguages($saved->getParameter('languages', array())); + + $start = $this->parseDateTime($saved->getParameter('createdStart')); + $end = $this->parseDateTime($saved->getParameter('createdEnd')); + + if ($start) { + $query->withDateCreatedAfter($start); + } + + if ($end) { + $query->withDateCreatedBefore($end); + } return $query; } - /** - * Builds the search form using the request. - * - * @param PhabricatorSavedQuery The query to populate the form with. - * @return AphrontFormView The built form. - */ public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { @@ -55,12 +50,44 @@ final class PhabricatorPasteSearchEngine ->loadHandles(); $author_tokens = mpull($handles, 'getFullName', 'getPHID'); - $form->appendChild( - id(new AphrontFormTokenizerControl()) - ->setDatasource('/typeahead/common/users/') - ->setName('authors') - ->setLabel(pht('Authors')) - ->setValue($author_tokens)); + $languages = $saved_query->getParameter('languages', array()); + $no_language = false; + foreach ($languages as $key => $language) { + if ($language === null) { + $no_language = true; + unset($languages[$key]); + continue; + } + } + + $form + ->appendChild( + id(new AphrontFormTokenizerControl()) + ->setDatasource('/typeahead/common/users/') + ->setName('authors') + ->setLabel(pht('Authors')) + ->setValue($author_tokens)) + ->appendChild( + id(new AphrontFormTextControl()) + ->setName('languages') + ->setLabel(pht('Languages')) + ->setValue(implode(', ', $languages))) + ->appendChild( + id(new AphrontFormCheckboxControl()) + ->addCheckbox( + 'noLanguage', + 1, + pht('Find Pastes with no specified language.'), + $no_language)); + + $this->buildDateRange( + $form, + $saved_query, + 'createdStart', + pht('Created After'), + 'createdEnd', + pht('Created Before')); + } protected function getURI($path) { @@ -69,7 +96,7 @@ final class PhabricatorPasteSearchEngine public function getBuiltinQueryNames() { $names = array( - 'all' => pht('All Pastes'), + 'all' => pht('All Pastes'), ); if ($this->requireViewer()->isLoggedIn()) { diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php index 23aa5e06fd..a242f3d714 100644 --- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php +++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php @@ -1334,6 +1334,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { 'type' => 'sql', 'name' => $this->getPatchPath('20130530.macrodatekey.sql'), ), + '20130530.pastekeys.sql' => array( + 'type' => 'sql', + 'name' => $this->getPatchPath('20130530.pastekeys.sql'), + ), ); } }