From ae1f0e3b1b68533d89c4372645ca04a100d9bf6e Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 22 Mar 2013 06:29:37 -0700 Subject: [PATCH] Introduce ReleephProjectQuery Summary: Adds a policy-aware query class for selecting Releeph projects. This doesn't really change anything. - Make `ReleephProject` implment `PhabricatorPolicyInterface`, beginning the long journey to make it policy-aware. - Implement `ReleephProjectQuery`, for querying projects using cursor-based, policy-aware paging. - Use it on the list view, so we load only ~100 projects instead of all of them. - Tweaked some of the URI routing stuff to make it a little more consistent with common practices. Ref T2714. Test Plan: {F36434} {F36435} Reviewers: edward Reviewed By: edward CC: aran Maniphest Tasks: T2714 Differential Revision: https://secure.phabricator.com/D5390 --- src/__phutil_library_map__.php | 8 +- .../PhabricatorApplicationReleeph.php | 3 +- .../project/ReleephProjectListController.php | 47 ++++++++--- .../releeph/query/ReleephProjectQuery.php | 79 +++++++++++++++++++ .../releeph/storage/ReleephProject.php | 20 ++++- 5 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 src/applications/releeph/query/ReleephProjectQuery.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e2eb1ec777..be2b2af57c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1631,6 +1631,7 @@ phutil_register_library_map(array( 'ReleephProjectCreateController' => 'applications/releeph/controller/project/ReleephProjectCreateController.php', 'ReleephProjectEditController' => 'applications/releeph/controller/project/ReleephProjectEditController.php', 'ReleephProjectListController' => 'applications/releeph/controller/project/ReleephProjectListController.php', + 'ReleephProjectQuery' => 'applications/releeph/query/ReleephProjectQuery.php', 'ReleephProjectView' => 'applications/releeph/view/ReleephProjectView.php', 'ReleephProjectViewController' => 'applications/releeph/controller/project/ReleephProjectViewController.php', 'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php', @@ -3268,11 +3269,16 @@ phutil_register_library_map(array( 'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification', 'ReleephObjectHandleLoader' => 'ObjectHandleLoader', 'ReleephOriginalCommitFieldSpecification' => 'ReleephFieldSpecification', - 'ReleephProject' => 'ReleephDAO', + 'ReleephProject' => + array( + 0 => 'ReleephDAO', + 1 => 'PhabricatorPolicyInterface', + ), 'ReleephProjectActionController' => 'ReleephController', 'ReleephProjectCreateController' => 'ReleephController', 'ReleephProjectEditController' => 'ReleephController', 'ReleephProjectListController' => 'PhabricatorController', + 'ReleephProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'ReleephProjectView' => 'AphrontView', 'ReleephProjectViewController' => 'ReleephController', 'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification', diff --git a/src/applications/releeph/application/PhabricatorApplicationReleeph.php b/src/applications/releeph/application/PhabricatorApplicationReleeph.php index 4512ba0d65..bc25016828 100644 --- a/src/applications/releeph/application/PhabricatorApplicationReleeph.php +++ b/src/applications/releeph/application/PhabricatorApplicationReleeph.php @@ -35,8 +35,7 @@ final class PhabricatorApplicationReleeph extends PhabricatorApplication { '/releeph/' => array( '' => 'ReleephProjectListController', 'project/' => array( - '' => 'ReleephProjectListController', - 'inactive/' => 'ReleephProjectListController', + '(?:(?Pactive|inactive)/)?' => 'ReleephProjectListController', 'create/' => 'ReleephProjectCreateController', '(?P[1-9]\d*)/' => array( '' => 'ReleephProjectViewController', diff --git a/src/applications/releeph/controller/project/ReleephProjectListController.php b/src/applications/releeph/controller/project/ReleephProjectListController.php index e00709d086..3c76d2ba5e 100644 --- a/src/applications/releeph/controller/project/ReleephProjectListController.php +++ b/src/applications/releeph/controller/project/ReleephProjectListController.php @@ -2,15 +2,37 @@ final class ReleephProjectListController extends PhabricatorController { - public function processRequest() { - $path = $this->getRequest()->getRequestURI()->getPath(); - $is_active = strpos($path, 'inactive/') === false; + private $filter; - $releeph_projects = mfilter( - id(new ReleephProject())->loadAll(), - 'getIsActive', - !$is_active); - $releeph_projects = msort($releeph_projects, 'getName'); + public function willProcessRequest(array $data) { + $this->filter = idx($data, 'filter', 'active'); + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $query = id(new ReleephProjectQuery()) + ->setViewer($user) + ->setOrder(ReleephProjectQuery::ORDER_NAME); + + switch ($this->filter) { + case 'inactive': + $query->withActive(0); + $is_active = false; + break; + case 'active': + $query->withActive(1); + $is_active = true; + break; + default: + throw new Exception("Unknown filter '{$this->filter}'!"); + } + + $pager = new AphrontCursorPagerView(); + $pager->readFromRequest($request); + + $releeph_projects = $query->executeWithCursorPager($pager); $releeph_projects_set = new LiskDAOSet(); foreach ($releeph_projects as $releeph_project) { @@ -60,10 +82,13 @@ final class ReleephProjectListController extends PhabricatorController { $panel->addButton($create_new_project_button); } - return $this->buildStandardPageResponse( - $panel, + return $this->buildApplicationPage( array( - 'title' => 'List Releeph Projects' + $panel, + $pager, + ), + array( + 'title' => 'List Releeph Projects', )); } diff --git a/src/applications/releeph/query/ReleephProjectQuery.php b/src/applications/releeph/query/ReleephProjectQuery.php new file mode 100644 index 0000000000..5fa215cf0b --- /dev/null +++ b/src/applications/releeph/query/ReleephProjectQuery.php @@ -0,0 +1,79 @@ +active = $active; + return $this; + } + + public function setOrder($order) { + $this->order = $order; + return $this; + } + + public function loadPage() { + $table = new ReleephProject(); + $conn_r = $table->establishConnection('r'); + + $rows = queryfx_all( + $conn_r, + 'SELECT * FROM %T %Q %Q %Q', + $table->getTableName(), + $this->buildWhereClause($conn_r), + $this->buildOrderClause($conn_r), + $this->buildLimitClause($conn_r)); + + return $table->loadAllFromArray($rows); + } + + private function buildWhereClause(AphrontDatabaseConnection $conn_r) { + $where = array(); + + if ($this->active !== null) { + $where[] = qsprintf( + $conn_r, + 'isActive = %d', + $this->active); + } + + $where[] = $this->buildPagingClause($conn_r); + + return $this->formatWhereClause($where); + } + + protected function getReversePaging() { + switch ($this->order) { + case self::ORDER_NAME: + return true; + } + return parent::getReversePaging(); + } + + protected function getPagingValue($result) { + switch ($this->order) { + case self::ORDER_NAME: + return $result->getName(); + } + return parent::getPagingValue(); + } + + protected function getPagingColumn() { + switch ($this->order) { + case self::ORDER_NAME: + return 'name'; + case self::ORDER_ID: + return parent::getPagingColumn(); + default: + throw new Exception("Uknown order '{$this->order}'!"); + } + } + +} diff --git a/src/applications/releeph/storage/ReleephProject.php b/src/applications/releeph/storage/ReleephProject.php index 1337340da2..8c4b454d15 100644 --- a/src/applications/releeph/storage/ReleephProject.php +++ b/src/applications/releeph/storage/ReleephProject.php @@ -1,6 +1,7 @@