mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Add a date range query to Macros
Summary: Ref T1163. Ref T2625. This could probably use some tweaks, but I kept things mostly-generic. I added a new control for freeform dates so we can have it render help or whatever later on. Test Plan: See screenshots. Reviewers: chad, btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T2625, T1163 Differential Revision: https://secure.phabricator.com/D6084
This commit is contained in:
parent
32f91557f8
commit
bccc1e1244
8 changed files with 182 additions and 0 deletions
2
resources/sql/patches/20130530.macrodatekey.sql
Normal file
2
resources/sql/patches/20130530.macrodatekey.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_file.file_imagemacro
|
||||
ADD KEY `key_dateCreated` (dateCreated);
|
|
@ -677,6 +677,7 @@ phutil_register_library_map(array(
|
|||
'PHUIFeedStoryExample' => 'applications/uiexample/examples/PHUIFeedStoryExample.php',
|
||||
'PHUIFeedStoryView' => 'view/phui/PHUIFeedStoryView.php',
|
||||
'PHUIFormDividerControl' => 'view/form/control/PHUIFormDividerControl.php',
|
||||
'PHUIFormFreeformDateControl' => 'view/form/control/PHUIFormFreeformDateControl.php',
|
||||
'PHUIFormMultiSubmitControl' => 'view/form/control/PHUIFormMultiSubmitControl.php',
|
||||
'PHUIFormPageView' => 'view/form/PHUIFormPageView.php',
|
||||
'PHUIIconExample' => 'applications/uiexample/examples/PHUIIconExample.php',
|
||||
|
@ -2470,6 +2471,7 @@ phutil_register_library_map(array(
|
|||
'PHUIFeedStoryExample' => 'PhabricatorUIExample',
|
||||
'PHUIFeedStoryView' => 'AphrontView',
|
||||
'PHUIFormDividerControl' => 'AphrontFormControl',
|
||||
'PHUIFormFreeformDateControl' => 'AphrontFormControl',
|
||||
'PHUIFormMultiSubmitControl' => 'AphrontFormControl',
|
||||
'PHUIFormPageView' => 'AphrontView',
|
||||
'PHUIIconExample' => 'PhabricatorUIExample',
|
||||
|
|
|
@ -11,6 +11,8 @@ final class PhabricatorMacroQuery
|
|||
private $authors;
|
||||
private $names;
|
||||
private $nameLike;
|
||||
private $dateCreatedAfter;
|
||||
private $dateCreatedBefore;
|
||||
|
||||
private $status = 'status-any';
|
||||
const STATUS_ANY = 'status-any';
|
||||
|
@ -55,6 +57,16 @@ final class PhabricatorMacroQuery
|
|||
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() {
|
||||
$macro_table = new PhabricatorFileImageMacro();
|
||||
$conn = $macro_table->establishConnection('r');
|
||||
|
@ -125,6 +137,20 @@ final class PhabricatorMacroQuery
|
|||
throw new Exception("Unknown status '{$this->status}'!");
|
||||
}
|
||||
|
||||
if ($this->dateCreatedAfter) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'm.dateCreated >= %d',
|
||||
$this->dateCreatedAfter);
|
||||
}
|
||||
|
||||
if ($this->dateCreatedBefore) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'm.dateCreated <= %d',
|
||||
$this->dateCreatedBefore);
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn);
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
|
|
|
@ -12,6 +12,8 @@ final class PhabricatorMacroSearchEngine
|
|||
$saved->setParameter('status', $request->getStr('status'));
|
||||
$saved->setParameter('names', $request->getStrList('names'));
|
||||
$saved->setParameter('nameLike', $request->getStr('nameLike'));
|
||||
$saved->setParameter('createdStart', $request->getStr('createdStart'));
|
||||
$saved->setParameter('createdEnd', $request->getStr('createdEnd'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
@ -39,6 +41,17 @@ final class PhabricatorMacroSearchEngine
|
|||
$query->withNameLike($like);
|
||||
}
|
||||
|
||||
$start = $this->parseDateTime($saved->getParameter('createdStart'));
|
||||
$end = $this->parseDateTime($saved->getParameter('createdEnd'));
|
||||
|
||||
if ($start) {
|
||||
$query->withDateCreatedAfter($start);
|
||||
}
|
||||
|
||||
if ($end) {
|
||||
$query->withDateCreatedBefore($end);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -79,6 +92,14 @@ final class PhabricatorMacroSearchEngine
|
|||
->setName('names')
|
||||
->setLabel(pht('Exact Names'))
|
||||
->setValue($names));
|
||||
|
||||
$this->buildDateRange(
|
||||
$form,
|
||||
$saved_query,
|
||||
'createdStart',
|
||||
pht('Created After'),
|
||||
'createdEnd',
|
||||
pht('Created Before'));
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
|
|
|
@ -131,6 +131,14 @@ final class PhabricatorApplicationSearchController
|
|||
|
||||
$engine->buildSearchForm($form, $saved_query);
|
||||
|
||||
$errors = $engine->getErrors();
|
||||
if ($errors) {
|
||||
$run_query = false;
|
||||
$errors = id(new AphrontErrorView())
|
||||
->setTitle(pht('Query Errors'))
|
||||
->setErrors($errors);
|
||||
}
|
||||
|
||||
$submit = id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Execute Query'));
|
||||
|
||||
|
@ -184,6 +192,10 @@ final class PhabricatorApplicationSearchController
|
|||
}
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
$nav->appendChild($errors);
|
||||
}
|
||||
|
||||
if ($named_query) {
|
||||
$title = pht('Query: %s', $named_query->getQueryName());
|
||||
} else {
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
*
|
||||
* @task builtin Builtin Queries
|
||||
* @task uri Query URIs
|
||||
* @task dates Date Filters
|
||||
*
|
||||
* @group search
|
||||
*/
|
||||
abstract class PhabricatorApplicationSearchEngine {
|
||||
|
||||
private $viewer;
|
||||
private $errors = array();
|
||||
|
||||
public function setViewer(PhabricatorUser $viewer) {
|
||||
$this->viewer = $viewer;
|
||||
|
@ -54,6 +56,14 @@ abstract class PhabricatorApplicationSearchEngine {
|
|||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $query);
|
||||
|
||||
public function getErrors() {
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function addError($error) {
|
||||
$this->errors[] = $error;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an application URI corresponding to the results page of a query.
|
||||
|
@ -182,4 +192,88 @@ abstract class PhabricatorApplicationSearchEngine {
|
|||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
throw new Exception("Builtin '{$query_key}' is not supported!");
|
||||
}
|
||||
|
||||
|
||||
/* -( Dates )-------------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* @task dates
|
||||
*/
|
||||
protected function parseDateTime($date_time) {
|
||||
if (!strlen($date_time)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$timezone = new DateTimeZone($viewer->getTimezoneIdentifier());
|
||||
|
||||
try {
|
||||
$date = new DateTime($date_time, $timezone);
|
||||
$timestamp = $date->format('U');
|
||||
} catch (Exception $e) {
|
||||
$timestamp = null;
|
||||
}
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @task dates
|
||||
*/
|
||||
protected function buildDateRange(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved_query,
|
||||
$start_key,
|
||||
$start_name,
|
||||
$end_key,
|
||||
$end_name) {
|
||||
|
||||
$start_str = $saved_query->getParameter($start_key);
|
||||
$start = null;
|
||||
if (strlen($start_str)) {
|
||||
$start = $this->parseDateTime($start_str);
|
||||
if (!$start) {
|
||||
$this->addError(
|
||||
pht(
|
||||
'"%s" date can not be parsed.',
|
||||
$start_name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$end_str = $saved_query->getParameter($end_key);
|
||||
$end = null;
|
||||
if (strlen($end_str)) {
|
||||
$end = $this->parseDateTime($end_str);
|
||||
if (!$end) {
|
||||
$this->addError(
|
||||
pht(
|
||||
'"%s" date can not be parsed.',
|
||||
$end_name));
|
||||
}
|
||||
}
|
||||
|
||||
if ($start && $end && ($start >= $end)) {
|
||||
$this->addError(
|
||||
pht(
|
||||
'"%s" must be a date before "%s".',
|
||||
$start_name,
|
||||
$end_name));
|
||||
}
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new PHUIFormFreeformDateControl())
|
||||
->setName($start_key)
|
||||
->setLabel($start_name)
|
||||
->setValue($start_str))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setName($end_key)
|
||||
->setLabel($end_name)
|
||||
->setValue($end_str));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1330,6 +1330,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
|||
'type' => 'php',
|
||||
'name' => $this->getPatchPath('20130530.sessionhash.php'),
|
||||
),
|
||||
'20130530.macrodatekey.sql' => array(
|
||||
'type' => 'sql',
|
||||
'name' => $this->getPatchPath('20130530.macrodatekey.sql'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
21
src/view/form/control/PHUIFormFreeformDateControl.php
Normal file
21
src/view/form/control/PHUIFormFreeformDateControl.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
final class PHUIFormFreeformDateControl extends AphrontFormControl {
|
||||
|
||||
protected function getCustomControlClass() {
|
||||
return 'aphront-form-control-text';
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
return javelin_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'text',
|
||||
'name' => $this->getName(),
|
||||
'value' => $this->getValue(),
|
||||
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||
'id' => $this->getID(),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue