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
			
			
This commit is contained in:
		
							
								
								
									
										5
									
								
								resources/sql/patches/20130530.pastekeys.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								resources/sql/patches/20130530.pastekeys.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
| @@ -10,6 +10,10 @@ final class PhabricatorPasteQuery | |||||||
|  |  | ||||||
|   private $needContent; |   private $needContent; | ||||||
|   private $needRawContent; |   private $needRawContent; | ||||||
|  |   private $languages; | ||||||
|  |   private $includeNoLanguage; | ||||||
|  |   private $dateCreatedAfter; | ||||||
|  |   private $dateCreatedBefore; | ||||||
|  |  | ||||||
|   public function withIDs(array $ids) { |   public function withIDs(array $ids) { | ||||||
|     $this->ids = $ids; |     $this->ids = $ids; | ||||||
| @@ -41,6 +45,28 @@ final class PhabricatorPasteQuery | |||||||
|     return $this; |     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() { |   protected function loadPage() { | ||||||
|     $table = new PhabricatorPaste(); |     $table = new PhabricatorPaste(); | ||||||
|     $conn_r = $table->establishConnection('r'); |     $conn_r = $table->establishConnection('r'); | ||||||
| @@ -107,6 +133,27 @@ final class PhabricatorPasteQuery | |||||||
|         $this->parentPHIDs); |         $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); |     return $this->formatWhereClause($where); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,51 +1,46 @@ | |||||||
| <?php | <?php | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Provides search functionality for the paste application. |  | ||||||
|  * |  | ||||||
|  * @group search |  | ||||||
|  */ |  | ||||||
| final class PhabricatorPasteSearchEngine | final class PhabricatorPasteSearchEngine | ||||||
|   extends PhabricatorApplicationSearchEngine { |   extends PhabricatorApplicationSearchEngine { | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * Create a saved query object from the request. |  | ||||||
|    * |  | ||||||
|    * @param AphrontRequest The search request. |  | ||||||
|    * @return The saved query that is built. |  | ||||||
|    */ |  | ||||||
|   public function buildSavedQueryFromRequest(AphrontRequest $request) { |   public function buildSavedQueryFromRequest(AphrontRequest $request) { | ||||||
|     $saved = new PhabricatorSavedQuery(); |     $saved = new PhabricatorSavedQuery(); | ||||||
|     $saved->setParameter( |     $saved->setParameter( | ||||||
|       'authorPHIDs', |       'authorPHIDs', | ||||||
|       array_values($request->getArr('authors'))); |       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; |     return $saved; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * Executes the saved query. |  | ||||||
|    * |  | ||||||
|    * @param PhabricatorSavedQuery |  | ||||||
|    * @return The result of the query. |  | ||||||
|    */ |  | ||||||
|   public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { |   public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { | ||||||
|     $query = id(new PhabricatorPasteQuery()) |     $query = id(new PhabricatorPasteQuery()) | ||||||
|       ->needContent(true) |       ->needContent(true) | ||||||
|       ->withIDs($saved->getParameter('ids', array())) |  | ||||||
|       ->withPHIDs($saved->getParameter('phids', array())) |  | ||||||
|       ->withAuthorPHIDs($saved->getParameter('authorPHIDs', 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; |     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( |   public function buildSearchForm( | ||||||
|     AphrontFormView $form, |     AphrontFormView $form, | ||||||
|     PhabricatorSavedQuery $saved_query) { |     PhabricatorSavedQuery $saved_query) { | ||||||
| @@ -55,12 +50,44 @@ final class PhabricatorPasteSearchEngine | |||||||
|       ->loadHandles(); |       ->loadHandles(); | ||||||
|     $author_tokens = mpull($handles, 'getFullName', 'getPHID'); |     $author_tokens = mpull($handles, 'getFullName', 'getPHID'); | ||||||
|  |  | ||||||
|     $form->appendChild( |     $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()) |         id(new AphrontFormTokenizerControl()) | ||||||
|           ->setDatasource('/typeahead/common/users/') |           ->setDatasource('/typeahead/common/users/') | ||||||
|           ->setName('authors') |           ->setName('authors') | ||||||
|           ->setLabel(pht('Authors')) |           ->setLabel(pht('Authors')) | ||||||
|         ->setValue($author_tokens)); |           ->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) { |   protected function getURI($path) { | ||||||
|   | |||||||
| @@ -1334,6 +1334,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList { | |||||||
|         'type' => 'sql', |         'type' => 'sql', | ||||||
|         'name' => $this->getPatchPath('20130530.macrodatekey.sql'), |         'name' => $this->getPatchPath('20130530.macrodatekey.sql'), | ||||||
|       ), |       ), | ||||||
|  |       '20130530.pastekeys.sql' => array( | ||||||
|  |         'type' => 'sql', | ||||||
|  |         'name' => $this->getPatchPath('20130530.pastekeys.sql'), | ||||||
|  |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley