@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator

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

+116 -33
+5
resources/sql/patches/20130530.pastekeys.sql
··· 1 + ALTER TABLE {$NAMESPACE}_pastebin.pastebin_paste 2 + ADD KEY `key_dateCreated` (dateCreated); 3 + 4 + ALTER TABLE {$NAMESPACE}_pastebin.pastebin_paste 5 + ADD KEY `key_language` (language);
+47
src/applications/paste/query/PhabricatorPasteQuery.php
··· 10 10 11 11 private $needContent; 12 12 private $needRawContent; 13 + private $languages; 14 + private $includeNoLanguage; 15 + private $dateCreatedAfter; 16 + private $dateCreatedBefore; 13 17 14 18 public function withIDs(array $ids) { 15 19 $this->ids = $ids; ··· 41 45 return $this; 42 46 } 43 47 48 + public function withLanguages(array $languages) { 49 + $this->includeNoLanguage = false; 50 + foreach ($languages as $key => $language) { 51 + if ($language === null) { 52 + $languages[$key] = ''; 53 + continue; 54 + } 55 + } 56 + $this->languages = $languages; 57 + return $this; 58 + } 59 + 60 + public function withDateCreatedBefore($date_created_before) { 61 + $this->dateCreatedBefore = $date_created_before; 62 + return $this; 63 + } 64 + 65 + public function withDateCreatedAfter($date_created_after) { 66 + $this->dateCreatedAfter = $date_created_after; 67 + return $this; 68 + } 69 + 44 70 protected function loadPage() { 45 71 $table = new PhabricatorPaste(); 46 72 $conn_r = $table->establishConnection('r'); ··· 105 131 $conn_r, 106 132 'parentPHID IN (%Ls)', 107 133 $this->parentPHIDs); 134 + } 135 + 136 + if ($this->languages) { 137 + $where[] = qsprintf( 138 + $conn_r, 139 + 'language IN (%Ls)', 140 + $this->languages); 141 + } 142 + 143 + if ($this->dateCreatedAfter) { 144 + $where[] = qsprintf( 145 + $conn_r, 146 + 'dateCreated >= %d', 147 + $this->dateCreatedAfter); 148 + } 149 + 150 + if ($this->dateCreatedBefore) { 151 + $where[] = qsprintf( 152 + $conn_r, 153 + 'dateCreated <= %d', 154 + $this->dateCreatedBefore); 108 155 } 109 156 110 157 return $this->formatWhereClause($where);
+60 -33
src/applications/paste/query/PhabricatorPasteSearchEngine.php
··· 1 1 <?php 2 2 3 - /** 4 - * Provides search functionality for the paste application. 5 - * 6 - * @group search 7 - */ 8 3 final class PhabricatorPasteSearchEngine 9 4 extends PhabricatorApplicationSearchEngine { 10 5 11 - /** 12 - * Create a saved query object from the request. 13 - * 14 - * @param AphrontRequest The search request. 15 - * @return The saved query that is built. 16 - */ 17 6 public function buildSavedQueryFromRequest(AphrontRequest $request) { 18 7 $saved = new PhabricatorSavedQuery(); 19 8 $saved->setParameter( 20 9 'authorPHIDs', 21 10 array_values($request->getArr('authors'))); 22 11 12 + $languages = $request->getStrList('languages'); 13 + if ($request->getBool('noLanguage')) { 14 + $languages[] = null; 15 + } 16 + $saved->setParameter('languages', $languages); 17 + 18 + $saved->setParameter('createdStart', $request->getStr('createdStart')); 19 + $saved->setParameter('createdEnd', $request->getStr('createdEnd')); 20 + 23 21 return $saved; 24 22 } 25 23 26 - /** 27 - * Executes the saved query. 28 - * 29 - * @param PhabricatorSavedQuery 30 - * @return The result of the query. 31 - */ 32 24 public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 33 25 $query = id(new PhabricatorPasteQuery()) 34 26 ->needContent(true) 35 - ->withIDs($saved->getParameter('ids', array())) 36 - ->withPHIDs($saved->getParameter('phids', array())) 37 27 ->withAuthorPHIDs($saved->getParameter('authorPHIDs', array())) 38 - ->withParentPHIDs($saved->getParameter('parentPHIDs', array())); 28 + ->withLanguages($saved->getParameter('languages', array())); 29 + 30 + $start = $this->parseDateTime($saved->getParameter('createdStart')); 31 + $end = $this->parseDateTime($saved->getParameter('createdEnd')); 32 + 33 + if ($start) { 34 + $query->withDateCreatedAfter($start); 35 + } 36 + 37 + if ($end) { 38 + $query->withDateCreatedBefore($end); 39 + } 39 40 40 41 return $query; 41 42 } 42 43 43 - /** 44 - * Builds the search form using the request. 45 - * 46 - * @param PhabricatorSavedQuery The query to populate the form with. 47 - * @return AphrontFormView The built form. 48 - */ 49 44 public function buildSearchForm( 50 45 AphrontFormView $form, 51 46 PhabricatorSavedQuery $saved_query) { ··· 55 50 ->loadHandles(); 56 51 $author_tokens = mpull($handles, 'getFullName', 'getPHID'); 57 52 58 - $form->appendChild( 59 - id(new AphrontFormTokenizerControl()) 60 - ->setDatasource('/typeahead/common/users/') 61 - ->setName('authors') 62 - ->setLabel(pht('Authors')) 63 - ->setValue($author_tokens)); 53 + $languages = $saved_query->getParameter('languages', array()); 54 + $no_language = false; 55 + foreach ($languages as $key => $language) { 56 + if ($language === null) { 57 + $no_language = true; 58 + unset($languages[$key]); 59 + continue; 60 + } 61 + } 62 + 63 + $form 64 + ->appendChild( 65 + id(new AphrontFormTokenizerControl()) 66 + ->setDatasource('/typeahead/common/users/') 67 + ->setName('authors') 68 + ->setLabel(pht('Authors')) 69 + ->setValue($author_tokens)) 70 + ->appendChild( 71 + id(new AphrontFormTextControl()) 72 + ->setName('languages') 73 + ->setLabel(pht('Languages')) 74 + ->setValue(implode(', ', $languages))) 75 + ->appendChild( 76 + id(new AphrontFormCheckboxControl()) 77 + ->addCheckbox( 78 + 'noLanguage', 79 + 1, 80 + pht('Find Pastes with no specified language.'), 81 + $no_language)); 82 + 83 + $this->buildDateRange( 84 + $form, 85 + $saved_query, 86 + 'createdStart', 87 + pht('Created After'), 88 + 'createdEnd', 89 + pht('Created Before')); 90 + 64 91 } 65 92 66 93 protected function getURI($path) { ··· 69 96 70 97 public function getBuiltinQueryNames() { 71 98 $names = array( 72 - 'all' => pht('All Pastes'), 99 + 'all' => pht('All Pastes'), 73 100 ); 74 101 75 102 if ($this->requireViewer()->isLoggedIn()) {
+4
src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
··· 1334 1334 'type' => 'sql', 1335 1335 'name' => $this->getPatchPath('20130530.macrodatekey.sql'), 1336 1336 ), 1337 + '20130530.pastekeys.sql' => array( 1338 + 'type' => 'sql', 1339 + 'name' => $this->getPatchPath('20130530.pastekeys.sql'), 1340 + ), 1337 1341 ); 1338 1342 } 1339 1343 }