mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-03 03:11:01 +01:00
Update Phrequent to use new search infrastructure.
Summary: This updates Phrequent to use new the search infrastructure. Now it looks like: {F60141} I've also added the policy infrastructure stubs, but it's probably not even close to being right in terms of enforcing policies (in particular being able to see time tracked against objects the user wouldn't normally be able to see). At some point I'd like to be able to filter on the objects that the time is tracked against, but I don't believe there's a tokenizer / readahead control that allows you to type any kind of object. Test Plan: Clicked around the new interface, created some custom queries and saved them. Reviewers: epriestley CC: Korvin, aran Maniphest Tasks: T3870 Differential Revision: https://secure.phabricator.com/D7163
This commit is contained in:
parent
27df293a96
commit
e4a07e01b5
7 changed files with 331 additions and 312 deletions
src
__phutil_library_map__.php
applications/phrequent
|
@ -1917,6 +1917,7 @@ phutil_register_library_map(array(
|
|||
'PhrequentController' => 'applications/phrequent/controller/PhrequentController.php',
|
||||
'PhrequentDAO' => 'applications/phrequent/storage/PhrequentDAO.php',
|
||||
'PhrequentListController' => 'applications/phrequent/controller/PhrequentListController.php',
|
||||
'PhrequentSearchEngine' => 'applications/phrequent/query/PhrequentSearchEngine.php',
|
||||
'PhrequentTrackController' => 'applications/phrequent/controller/PhrequentTrackController.php',
|
||||
'PhrequentTrackableInterface' => 'applications/phrequent/interface/PhrequentTrackableInterface.php',
|
||||
'PhrequentUIEventListener' => 'applications/phrequent/event/PhrequentUIEventListener.php',
|
||||
|
@ -4130,11 +4131,20 @@ phutil_register_library_map(array(
|
|||
'PhortuneWePayPaymentProvider' => 'PhortunePaymentProvider',
|
||||
'PhrequentController' => 'PhabricatorController',
|
||||
'PhrequentDAO' => 'PhabricatorLiskDAO',
|
||||
'PhrequentListController' => 'PhrequentController',
|
||||
'PhrequentListController' =>
|
||||
array(
|
||||
0 => 'PhrequentController',
|
||||
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||
),
|
||||
'PhrequentSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhrequentTrackController' => 'PhrequentController',
|
||||
'PhrequentUIEventListener' => 'PhutilEventListener',
|
||||
'PhrequentUserTime' => 'PhrequentDAO',
|
||||
'PhrequentUserTimeQuery' => 'PhabricatorOffsetPagedQuery',
|
||||
'PhrequentUserTime' =>
|
||||
array(
|
||||
0 => 'PhrequentDAO',
|
||||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'PhrequentUserTimeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhrictionActionConstants' => 'PhrictionConstants',
|
||||
'PhrictionActionMenuEventListener' => 'PhutilEventListener',
|
||||
'PhrictionChangeType' => 'PhrictionConstants',
|
||||
|
|
|
@ -35,8 +35,7 @@ final class PhabricatorApplicationPhrequent extends PhabricatorApplication {
|
|||
public function getRoutes() {
|
||||
return array(
|
||||
'/phrequent/' => array(
|
||||
'' => 'PhrequentListController',
|
||||
'view/(?P<view>\w+)/' => 'PhrequentListController',
|
||||
'(?:query/(?P<queryKey>[^/]+)/)?' => 'PhrequentListController',
|
||||
'track/(?P<verb>[a-z]+)/(?P<phid>[^/]+)/'
|
||||
=> 'PhrequentTrackController'
|
||||
),
|
||||
|
|
|
@ -2,18 +2,17 @@
|
|||
|
||||
abstract class PhrequentController extends PhabricatorController {
|
||||
|
||||
protected function buildNav($view) {
|
||||
protected function buildSideNavView() {
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI('/phrequent/view/'));
|
||||
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
$nav->addLabel(pht('User Times'));
|
||||
$nav->addFilter('current', pht('Currently Tracking'));
|
||||
$nav->addFilter('recent', pht('Recent Activity'));
|
||||
$nav->addLabel('All Times');
|
||||
$nav->addFilter('allcurrent', pht('Currently Tracking'));
|
||||
$nav->addFilter('allrecent', pht('Recent Activity'));
|
||||
id(new PhrequentSearchEngine())
|
||||
->setViewer($user)
|
||||
->addNavigationItems($nav->getMenu());
|
||||
|
||||
$nav->selectFilter($view);
|
||||
$nav->selectFilter(null);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
|
|
@ -1,290 +1,95 @@
|
|||
<?php
|
||||
|
||||
final class PhrequentListController extends PhrequentController {
|
||||
final class PhrequentListController extends PhrequentController
|
||||
implements PhabricatorApplicationSearchResultsControllerInterface {
|
||||
|
||||
private $view;
|
||||
private $queryKey;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->view = idx($data, 'view', "current");
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getArrToStrList($key) {
|
||||
$arr = $this->getRequest()->getArr($key);
|
||||
$arr = implode(',', $arr);
|
||||
return nonempty($arr, null);
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->queryKey = idx($data, 'queryKey');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
// Redirect to GET so URIs can be copy/pasted.
|
||||
|
||||
$order = $request->getStr('o');
|
||||
$order = nonempty($order, null);
|
||||
|
||||
$ended = $request->getStr('e');
|
||||
$ended = nonempty($ended, null);
|
||||
|
||||
$uri = $request->getRequestURI()
|
||||
->alter('users', $this->getArrToStrList('set_users'))
|
||||
->alter('o', $order)
|
||||
->alter('e', $ended);
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
}
|
||||
|
||||
$nav = $this->buildNav($this->view);
|
||||
|
||||
$has_user_filter = array(
|
||||
"current" => true,
|
||||
"recent" => true,
|
||||
);
|
||||
|
||||
$user_phids = $request->getStrList('users', array());
|
||||
if (isset($has_user_filter[$this->view])) {
|
||||
$user_phids = array($user->getPHID());
|
||||
}
|
||||
|
||||
switch ($this->view) {
|
||||
case "current":
|
||||
case "allcurrent":
|
||||
$order_key_default = "s";
|
||||
$ended_key_default = "n";
|
||||
break;
|
||||
case "recent":
|
||||
case "allrecent":
|
||||
$order_key_default = "s";
|
||||
$ended_key_default = "y";
|
||||
break;
|
||||
default:
|
||||
$order_key_default = "s";
|
||||
$ended_key_default = "a";
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($request->getStr('o', $order_key_default)) {
|
||||
case 's':
|
||||
$order = PhrequentUserTimeQuery::ORDER_STARTED;
|
||||
break;
|
||||
case 'e':
|
||||
$order = PhrequentUserTimeQuery::ORDER_ENDED;
|
||||
break;
|
||||
case 'd':
|
||||
$order = PhrequentUserTimeQuery::ORDER_DURATION;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown order!");
|
||||
}
|
||||
|
||||
switch ($request->getStr('e', $ended_key_default)) {
|
||||
case 'a':
|
||||
$ended = PhrequentUserTimeQuery::ENDED_ALL;
|
||||
break;
|
||||
case 'y':
|
||||
$ended = PhrequentUserTimeQuery::ENDED_YES;
|
||||
break;
|
||||
case 'n':
|
||||
$ended = PhrequentUserTimeQuery::ENDED_NO;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown ended!");
|
||||
}
|
||||
|
||||
$filter = new AphrontListFilterView();
|
||||
$filter->appendChild(
|
||||
$this->buildForm($user_phids, $order_key_default, $ended_key_default));
|
||||
|
||||
$query = new PhrequentUserTimeQuery();
|
||||
$query->setOrder($order);
|
||||
$query->setEnded($ended);
|
||||
$query->setUsers($user_phids);
|
||||
|
||||
$pager = new AphrontPagerView();
|
||||
$pager->setPageSize(500);
|
||||
$pager->setOffset($request->getInt('offset'));
|
||||
$pager->setURI($request->getRequestURI(), 'offset');
|
||||
|
||||
$logs = $query->executeWithOffsetPager($pager);
|
||||
|
||||
$title = pht('Time Tracked');
|
||||
|
||||
$table = $this->buildTableView($logs);
|
||||
$table->appendChild($pager);
|
||||
|
||||
$nav->appendChild(
|
||||
array(
|
||||
$filter,
|
||||
$table,
|
||||
$pager,
|
||||
));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName($title)
|
||||
->setHref($this->getApplicationURI('/')));
|
||||
|
||||
$nav->setCrumbs($crumbs);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$nav,
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
));
|
||||
$controller = id(new PhabricatorApplicationSearchController($request))
|
||||
->setQueryKey($this->queryKey)
|
||||
->setSearchEngine(new PhrequentSearchEngine())
|
||||
->setNavigation($this->buildSideNavView());
|
||||
|
||||
return $this->delegateToController($controller);
|
||||
}
|
||||
|
||||
protected function buildForm(array $user_phids, $order_key_default,
|
||||
$ended_key_default) {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user)
|
||||
->setAction($this->getApplicationURI("/view/custom/"));
|
||||
|
||||
$user_handles = id(new PhabricatorHandleQuery())
|
||||
->setViewer($user)
|
||||
->withPHIDs($user_phids)
|
||||
->execute();
|
||||
$tokens = array();
|
||||
foreach ($user_phids as $phid) {
|
||||
$tokens[$phid] = $user_handles[$phid]->getFullName();
|
||||
}
|
||||
$form->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource('/typeahead/common/searchowner/')
|
||||
->setName('set_users')
|
||||
->setLabel(pht('Users'))
|
||||
->setValue($tokens));
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormToggleButtonsControl())
|
||||
->setName('o')
|
||||
->setLabel(pht('Sort Order'))
|
||||
->setBaseURI($request->getRequestURI(), 'o')
|
||||
->setValue($request->getStr('o', $order_key_default))
|
||||
->setButtons(
|
||||
array(
|
||||
's' => pht('Started'),
|
||||
'e' => pht('Ended'),
|
||||
'd' => pht('Duration'),
|
||||
)));
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormToggleButtonsControl())
|
||||
->setName('e')
|
||||
->setLabel(pht('Ended'))
|
||||
->setBaseURI($request->getRequestURI(), 'e')
|
||||
->setValue($request->getStr('e', $ended_key_default))
|
||||
->setButtons(
|
||||
array(
|
||||
'y' => pht('Yes'),
|
||||
'n' => pht('No'),
|
||||
'a' => pht('All'),
|
||||
)));
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())->setValue(pht('Filter Objects')));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
protected function buildTableView(array $usertimes) {
|
||||
public function renderResultsList(
|
||||
array $usertimes,
|
||||
PhabricatorSavedQuery $query) {
|
||||
assert_instances_of($usertimes, 'PhrequentUserTime');
|
||||
|
||||
$user = $this->getRequest()->getUser();
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$phids = array();
|
||||
foreach ($usertimes as $usertime) {
|
||||
$phids[] = $usertime->getUserPHID();
|
||||
$phids[] = $usertime->getObjectPHID();
|
||||
}
|
||||
$phids[] = mpull($usertimes, 'getUserPHID');
|
||||
$phids[] = mpull($usertimes, 'getObjectPHID');
|
||||
$phids = array_mergev($phids);
|
||||
|
||||
$handles = $this->loadViewerHandles($phids);
|
||||
|
||||
$rows = array();
|
||||
$view = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
|
||||
foreach ($usertimes as $usertime) {
|
||||
$item = new PHUIObjectItemView();
|
||||
|
||||
if ($usertime->getObjectPHID() === null) {
|
||||
$item->setHeader($usertime->getNote());
|
||||
} else {
|
||||
$obj = $handles[$usertime->getObjectPHID()];
|
||||
$item->setHeader($obj->getLinkName());
|
||||
$item->setHref($obj->getURI());
|
||||
}
|
||||
$item->setObject($usertime);
|
||||
|
||||
$item->addByline(
|
||||
pht(
|
||||
'Tracked: %s',
|
||||
$handles[$usertime->getUserPHID()]->renderLink()));
|
||||
|
||||
$started_date = phabricator_date($usertime->getDateStarted(), $viewer);
|
||||
$item->addIcon('none', $started_date);
|
||||
|
||||
if ($usertime->getDateEnded() !== null) {
|
||||
$time_spent = $usertime->getDateEnded() - $usertime->getDateStarted();
|
||||
$time_ended = phabricator_datetime($usertime->getDateEnded(), $user);
|
||||
$time_ended = phabricator_datetime($usertime->getDateEnded(), $viewer);
|
||||
} else {
|
||||
$time_spent = time() - $usertime->getDateStarted();
|
||||
$time_ended = phutil_tag(
|
||||
'em',
|
||||
array(),
|
||||
pht('Ongoing'));
|
||||
}
|
||||
|
||||
$usertime_user = $handles[$usertime->getUserPHID()];
|
||||
$usertime_object = null;
|
||||
$object = null;
|
||||
if ($usertime->getObjectPHID() !== null) {
|
||||
$usertime_object = $handles[$usertime->getObjectPHID()];
|
||||
$object = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $usertime_object->getURI()
|
||||
),
|
||||
$usertime_object->getFullName());
|
||||
$time_spent = $time_spent == 0 ? 'none' :
|
||||
phabricator_format_relative_time_detailed($time_spent);
|
||||
|
||||
if ($usertime->getDateEnded() !== null) {
|
||||
$item->addAttribute(
|
||||
pht(
|
||||
'Tracked %s',
|
||||
$time_spent));
|
||||
$item->addAttribute(
|
||||
pht(
|
||||
'Ended on %s',
|
||||
$time_ended));
|
||||
} else {
|
||||
$object = phutil_tag(
|
||||
'em',
|
||||
array(),
|
||||
pht('None'));
|
||||
$item->addAttribute(
|
||||
pht(
|
||||
'Tracked %s so far',
|
||||
$time_spent));
|
||||
$item->setBarColor('green');
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
$object,
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $usertime_user->getURI()
|
||||
),
|
||||
$usertime_user->getFullName()),
|
||||
phabricator_datetime($usertime->getDateStarted(), $user),
|
||||
$time_ended,
|
||||
$time_spent == 0 ? 'none' :
|
||||
phabricator_format_relative_time_detailed($time_spent),
|
||||
$usertime->getNote()
|
||||
);
|
||||
$view->addItem($item);
|
||||
}
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setDeviceReadyTable(true);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
'Object',
|
||||
'User',
|
||||
'Started',
|
||||
'Ended',
|
||||
'Duration',
|
||||
'Note'
|
||||
));
|
||||
$table->setShortHeaders(
|
||||
array(
|
||||
'O',
|
||||
'U',
|
||||
'S',
|
||||
'E',
|
||||
'D',
|
||||
'Note',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'wide'
|
||||
));
|
||||
|
||||
return $table;
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
114
src/applications/phrequent/query/PhrequentSearchEngine.php
Normal file
114
src/applications/phrequent/query/PhrequentSearchEngine.php
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
final class PhrequentSearchEngine
|
||||
extends PhabricatorApplicationSearchEngine {
|
||||
|
||||
public function getPageSize(PhabricatorSavedQuery $saved) {
|
||||
return $saved->getParameter('limit', 1000);
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter(
|
||||
'userPHIDs',
|
||||
$this->readUsersFromRequest($request, 'users'));
|
||||
|
||||
$saved->setParameter('ended', $request->getStr('ended'));
|
||||
|
||||
$saved->setParameter('order', $request->getStr('order'));
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
$query = id(new PhrequentUserTimeQuery());
|
||||
|
||||
$user_phids = $saved->getParameter('userPHIDs');
|
||||
if ($user_phids) {
|
||||
$query->withUserPHIDs($user_phids);
|
||||
}
|
||||
|
||||
$ended = $saved->getParameter('ended');
|
||||
if ($ended != null) {
|
||||
$query->withEnded($ended);
|
||||
}
|
||||
|
||||
$order = $saved->getParameter('order');
|
||||
if ($order != null) {
|
||||
$query->setOrder($order);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function buildSearchForm(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved_query) {
|
||||
|
||||
$user_phids = $saved_query->getParameter('userPHIDs', array());
|
||||
$ended = $saved_query->getParameter(
|
||||
'ended', PhrequentUserTimeQuery::ENDED_ALL);
|
||||
$order = $saved_query->getParameter(
|
||||
'order', PhrequentUserTimeQuery::ORDER_ENDED_DESC);
|
||||
|
||||
$phids = array_merge($user_phids);
|
||||
$handles = id(new PhabricatorHandleQuery())
|
||||
->setViewer($this->requireViewer())
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource('/typeahead/common/users/')
|
||||
->setName('users')
|
||||
->setLabel(pht('Users'))
|
||||
->setValue($handles))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Ended'))
|
||||
->setName('ended')
|
||||
->setValue($ended)
|
||||
->setOptions(PhrequentUserTimeQuery::getEndedSearchOptions()))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Order'))
|
||||
->setName('order')
|
||||
->setValue($order)
|
||||
->setOptions(PhrequentUserTimeQuery::getOrderSearchOptions()));
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/phrequent/'.$path;
|
||||
}
|
||||
|
||||
public function getBuiltinQueryNames() {
|
||||
$names = array(
|
||||
'tracking' => pht('Currently Tracking'),
|
||||
'all' => pht('All Tracked'),
|
||||
);
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromBuiltin($query_key) {
|
||||
|
||||
$query = $this->newSavedQuery();
|
||||
$query->setQueryKey($query_key);
|
||||
|
||||
switch ($query_key) {
|
||||
case 'all':
|
||||
return $query
|
||||
->setParameter('order', PhrequentUserTimeQuery::ORDER_ENDED_DESC);
|
||||
case 'tracking':
|
||||
return $query
|
||||
->setParameter('ended', PhrequentUserTimeQuery::ENDED_NO)
|
||||
->setParameter('order', PhrequentUserTimeQuery::ORDER_ENDED_DESC);
|
||||
}
|
||||
|
||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +1,46 @@
|
|||
<?php
|
||||
|
||||
final class PhrequentUserTimeQuery extends PhabricatorOffsetPagedQuery {
|
||||
final class PhrequentUserTimeQuery
|
||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
const ORDER_ID = 'order-id';
|
||||
const ORDER_STARTED = 'order-started';
|
||||
const ORDER_ENDED = 'order-ended';
|
||||
const ORDER_DURATION = 'order-duration';
|
||||
const ORDER_ID_ASC = 0;
|
||||
const ORDER_ID_DESC = 1;
|
||||
const ORDER_STARTED_ASC = 2;
|
||||
const ORDER_STARTED_DESC = 3;
|
||||
const ORDER_ENDED_ASC = 4;
|
||||
const ORDER_ENDED_DESC = 5;
|
||||
const ORDER_DURATION_ASC = 6;
|
||||
const ORDER_DURATION_DESC = 7;
|
||||
|
||||
const ENDED_YES = "ended-yes";
|
||||
const ENDED_NO = "ended-no";
|
||||
const ENDED_ALL = "ended-all";
|
||||
const ENDED_YES = 0;
|
||||
const ENDED_NO = 1;
|
||||
const ENDED_ALL = 2;
|
||||
|
||||
private $userPHIDs;
|
||||
private $objectPHIDs;
|
||||
private $order = self::ORDER_ID;
|
||||
private $order = self::ORDER_ID_ASC;
|
||||
private $ended = self::ENDED_ALL;
|
||||
|
||||
public function setUsers($user_phids) {
|
||||
public function withUserPHIDs($user_phids) {
|
||||
$this->userPHIDs = $user_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setObjects($object_phids) {
|
||||
public function withObjectPHIDs($object_phids) {
|
||||
$this->objectPHIDs = $object_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withEnded($ended) {
|
||||
$this->ended = $ended;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setOrder($order) {
|
||||
$this->order = $order;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEnded($ended) {
|
||||
$this->ended = $ended;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$usertime_dao = new PhrequentUserTime();
|
||||
$conn = $usertime_dao->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn,
|
||||
'SELECT usertime.* FROM %T usertime %Q %Q %Q',
|
||||
$usertime_dao->getTableName(),
|
||||
$this->buildWhereClause($conn),
|
||||
$this->buildOrderClause($conn),
|
||||
$this->buildLimitClause($conn));
|
||||
|
||||
return $usertime_dao->loadAllFromArray($data);
|
||||
}
|
||||
|
||||
private function buildWhereClause(AphrontDatabaseConnection $conn) {
|
||||
$where = array();
|
||||
|
||||
|
@ -85,27 +75,100 @@ final class PhrequentUserTimeQuery extends PhabricatorOffsetPagedQuery {
|
|||
throw new Exception("Unknown ended '{$this->ended}'!");
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn);
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
}
|
||||
|
||||
private function buildOrderClause(AphrontDatabaseConnection $conn) {
|
||||
protected function getPagingColumn() {
|
||||
switch ($this->order) {
|
||||
case self::ORDER_ID:
|
||||
return 'ORDER BY id ASC';
|
||||
case self::ORDER_STARTED:
|
||||
return 'ORDER BY dateStarted DESC';
|
||||
case self::ORDER_ENDED:
|
||||
return 'ORDER BY dateEnded IS NULL, dateEnded DESC, dateStarted DESC';
|
||||
case self::ORDER_DURATION:
|
||||
return 'ORDER BY COALESCE(dateEnded, UNIX_TIMESTAMP()) - dateStarted '.
|
||||
'DESC';
|
||||
case self::ORDER_ID_ASC:
|
||||
case self::ORDER_ID_DESC:
|
||||
return 'id';
|
||||
case self::ORDER_STARTED_ASC:
|
||||
case self::ORDER_STARTED_DESC:
|
||||
return 'dateStarted';
|
||||
case self::ORDER_ENDED_ASC:
|
||||
case self::ORDER_ENDED_DESC:
|
||||
return 'dateEnded';
|
||||
case self::ORDER_DURATION_ASC:
|
||||
case self::ORDER_DURATION_DESC:
|
||||
return 'COALESCE(dateEnded, UNIX_TIMESTAMP()) - dateStarted';
|
||||
default:
|
||||
throw new Exception("Unknown order '{$this->order}'!");
|
||||
}
|
||||
}
|
||||
|
||||
protected function getPagingValue($result) {
|
||||
switch ($this->order) {
|
||||
case self::ORDER_ID_ASC:
|
||||
case self::ORDER_ID_DESC:
|
||||
return $result->getID();
|
||||
case self::ORDER_STARTED_ASC:
|
||||
case self::ORDER_STARTED_DESC:
|
||||
return $result->getDateStarted();
|
||||
case self::ORDER_ENDED_ASC:
|
||||
case self::ORDER_ENDED_DESC:
|
||||
return $result->getDateEnded();
|
||||
case self::ORDER_DURATION_ASC:
|
||||
case self::ORDER_DURATION_DESC:
|
||||
return ($result->getDateEnded() || time()) - $result->getDateStarted();
|
||||
default:
|
||||
throw new Exception("Unknown order '{$this->order}'!");
|
||||
}
|
||||
}
|
||||
|
||||
protected function getReversePaging() {
|
||||
switch ($this->order) {
|
||||
case self::ORDER_ID_ASC:
|
||||
case self::ORDER_STARTED_ASC:
|
||||
case self::ORDER_ENDED_ASC:
|
||||
case self::ORDER_DURATION_ASC:
|
||||
return true;
|
||||
case self::ORDER_ID_DESC:
|
||||
case self::ORDER_STARTED_DESC:
|
||||
case self::ORDER_ENDED_DESC:
|
||||
case self::ORDER_DURATION_DESC:
|
||||
return false;
|
||||
default:
|
||||
throw new Exception("Unknown order '{$this->order}'!");
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$usertime = new PhrequentUserTime();
|
||||
$conn = $usertime->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn,
|
||||
'SELECT usertime.* FROM %T usertime %Q %Q %Q',
|
||||
$usertime->getTableName(),
|
||||
$this->buildWhereClause($conn),
|
||||
$this->buildOrderClause($conn),
|
||||
$this->buildLimitClause($conn));
|
||||
|
||||
return $usertime->loadAllFromArray($data);
|
||||
}
|
||||
|
||||
/* -( Helper Functions ) --------------------------------------------------- */
|
||||
|
||||
public static function getEndedSearchOptions() {
|
||||
return array(
|
||||
self::ENDED_ALL => pht('All'),
|
||||
self::ENDED_NO => pht('No'),
|
||||
self::ENDED_YES => pht('Yes'));
|
||||
}
|
||||
|
||||
public static function getOrderSearchOptions() {
|
||||
return array(
|
||||
self::ORDER_STARTED_ASC => pht('by furthest start date'),
|
||||
self::ORDER_STARTED_DESC => pht('by nearest start date'),
|
||||
self::ORDER_ENDED_ASC => pht('by furthest end date'),
|
||||
self::ORDER_ENDED_DESC => pht('by nearest end date'),
|
||||
self::ORDER_DURATION_ASC => pht('by smallest duration'),
|
||||
self::ORDER_DURATION_DESC => pht('by largest duration'));
|
||||
}
|
||||
|
||||
public static function getUserTotalObjectsTracked(
|
||||
PhabricatorUser $user) {
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
/**
|
||||
* @group phrequent
|
||||
*/
|
||||
final class PhrequentUserTime extends PhrequentDAO {
|
||||
final class PhrequentUserTime extends PhrequentDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
|
||||
protected $userPHID;
|
||||
protected $objectPHID;
|
||||
|
@ -11,4 +12,32 @@ final class PhrequentUserTime extends PhrequentDAO {
|
|||
protected $dateStarted;
|
||||
protected $dateEnded;
|
||||
|
||||
public function getCapabilities() {
|
||||
return array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
);
|
||||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
$policy = PhabricatorPolicies::POLICY_NOONE;
|
||||
|
||||
switch ($capability) {
|
||||
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||
$policy = PhabricatorPolicies::POLICY_USER;
|
||||
break;
|
||||
}
|
||||
|
||||
return $policy;
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
return ($viewer->getPHID() == $this->getUserPHID());
|
||||
}
|
||||
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht(
|
||||
'The user who tracked time can always view it.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue