1
0
Fork 0
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:
epriestley 2013-05-30 17:32:12 -07:00
parent 32f91557f8
commit bccc1e1244
8 changed files with 182 additions and 0 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_file.file_imagemacro
ADD KEY `key_dateCreated` (dateCreated);

View file

@ -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',

View file

@ -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);

View file

@ -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) {

View file

@ -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 {

View file

@ -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));
}
}

View file

@ -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'),
),
);
}
}

View 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(),
));
}
}