mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-21 13:00:56 +01:00
Move Project list to use ManiphestTaskQuery
Summary: We decided to move away from driving everything through the search engine since it doesn't scale terribly well, so use ManiphestTaskQuery instead. Also link the open count and tweak some display stuff. Test Plan: Looked at project list, clicked open tasks link Reviewed By: tuomaspelkonen Reviewers: cadamo, aran, jungejason, tuomaspelkonen CC: aran, tuomaspelkonen Differential Revision: 608
This commit is contained in:
parent
62532ef26d
commit
cef7664d47
7 changed files with 49 additions and 105 deletions
|
@ -457,7 +457,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
|
||||
'PhabricatorProjectProfileEditController' => 'applications/project/controller/profileedit',
|
||||
'PhabricatorProjectStatus' => 'applications/project/constants/status',
|
||||
'PhabricatorProjectTransactionSearch' => 'applications/project/transactions/search',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
|
||||
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
|
||||
|
|
|
@ -29,6 +29,7 @@ final class ManiphestTaskQuery {
|
|||
private $includeUnowned = null;
|
||||
private $projectPHIDs = array();
|
||||
private $subscriberPHIDs = array();
|
||||
private $anyProject = false;
|
||||
|
||||
private $status = 'status-any';
|
||||
const STATUS_ANY = 'status-any';
|
||||
|
@ -129,6 +130,11 @@ final class ManiphestTaskQuery {
|
|||
return $this->rowCount;
|
||||
}
|
||||
|
||||
public function withAnyProject($any_project) {
|
||||
$this->anyProject = $any_project;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
|
||||
$task_dao = new ManiphestTask();
|
||||
|
@ -176,14 +182,18 @@ final class ManiphestTaskQuery {
|
|||
// multiple times. We use GROUP BY to make them distinct again.
|
||||
// - We want to treat the query as an intersection query, not a union
|
||||
// query. We sum the project count and require it be the same as the
|
||||
// number of projects we're searching for.
|
||||
// number of projects we're searching for. (If 'anyProject' is set,
|
||||
// we do union instead.)
|
||||
|
||||
$group = 'GROUP BY task.id';
|
||||
$count = ', COUNT(1) projectCount';
|
||||
$having = qsprintf(
|
||||
$conn,
|
||||
'HAVING projectCount = %d',
|
||||
count($this->projectPHIDs));
|
||||
|
||||
if (!$this->anyProject) {
|
||||
$count = ', COUNT(1) projectCount';
|
||||
$having = qsprintf(
|
||||
$conn,
|
||||
'HAVING projectCount = %d',
|
||||
count($this->projectPHIDs));
|
||||
}
|
||||
}
|
||||
|
||||
$order = $this->buildOrderClause($conn);
|
||||
|
|
|
@ -30,7 +30,7 @@ final class PhabricatorProjectStatus {
|
|||
|
||||
public static function getNameForStatus($status) {
|
||||
static $map = array(
|
||||
self::UNKNOWN => 'Who knows?',
|
||||
self::UNKNOWN => '',
|
||||
self::NOT_STARTED => 'Not started',
|
||||
self::IN_PROGRESS => 'In progress',
|
||||
self::ONGOING => 'Ongoing',
|
||||
|
|
|
@ -43,37 +43,39 @@ class PhabricatorProjectListController
|
|||
$handles = id(new PhabricatorObjectHandleData($author_phids))
|
||||
->loadHandles();
|
||||
|
||||
$project_phids = mpull($projects, 'getPHID');
|
||||
|
||||
$query = id(new ManiphestTaskQuery())
|
||||
->withProjects($project_phids)
|
||||
->withAnyProject(true)
|
||||
->withStatus(ManiphestTaskQuery::STATUS_OPEN)
|
||||
->setLimit(PHP_INT_MAX);
|
||||
|
||||
$tasks = $query->execute();
|
||||
$groups = array();
|
||||
foreach ($tasks as $task) {
|
||||
foreach ($task->getProjectPHIDs() as $phid) {
|
||||
$groups[$phid][] = $task;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$rows = array();
|
||||
foreach ($projects as $project) {
|
||||
$profile = $profiles[$project->getPHID()];
|
||||
$affiliations = $affil_groups[$project->getPHID()];
|
||||
$phid = $project->getPHID();
|
||||
|
||||
$documents = new PhabricatorProjectTransactionSearch($project->getPHID());
|
||||
// search all open documents by default
|
||||
$documents->setSearchOptions();
|
||||
$documents = $documents->executeSearch();
|
||||
$profile = $profiles[$phid];
|
||||
$affiliations = $affil_groups[$phid];
|
||||
|
||||
$documents_types = igroup($documents, 'documentType');
|
||||
$tasks = idx(
|
||||
$documents_types,
|
||||
PhabricatorPHIDConstants::PHID_TYPE_TASK);
|
||||
$tasks_amount = count($tasks);
|
||||
|
||||
// TODO: set up a relationship between the project and the arcanist's
|
||||
// project, to be able get the revisions.
|
||||
$revisions = idx(
|
||||
$documents_types,
|
||||
PhabricatorPHIDConstants::PHID_TYPE_DREV);
|
||||
$revisions_amount = count($revisions);
|
||||
$group = idx($groups, $phid, array());
|
||||
$task_count = count($group);
|
||||
|
||||
$population = count($affiliations);
|
||||
|
||||
$status = PhabricatorProjectStatus::getNameForStatus(
|
||||
$project->getStatus());
|
||||
|
||||
$blurb = nonempty(
|
||||
$profile->getBlurb(),
|
||||
'Oops!, nothing is known about this elusive project.');
|
||||
$blurb = $profile->getBlurb();
|
||||
$blurb = phutil_utf8_shorten($blurb, $columns = 100);
|
||||
|
||||
$rows[] = array(
|
||||
|
@ -82,8 +84,12 @@ class PhabricatorProjectListController
|
|||
$handles[$project->getAuthorPHID()]->renderLink(),
|
||||
phutil_escape_html($population),
|
||||
phutil_escape_html($status),
|
||||
phutil_escape_html($tasks_amount),
|
||||
// phutil_escape_html($revisions_amount),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/maniphest/view/all/?projects='.$phid,
|
||||
),
|
||||
phutil_escape_html($task_count)),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
|
@ -98,12 +104,11 @@ class PhabricatorProjectListController
|
|||
$table->setHeaders(
|
||||
array(
|
||||
'Project',
|
||||
'Blurb',
|
||||
'Description',
|
||||
'Mastermind',
|
||||
'Population',
|
||||
'Status',
|
||||
'Open Tasks',
|
||||
// 'Open Revisions',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
|
@ -112,9 +117,8 @@ class PhabricatorProjectListController
|
|||
'wide',
|
||||
'',
|
||||
'right',
|
||||
'pri',
|
||||
'',
|
||||
'right',
|
||||
// 'right',
|
||||
'action',
|
||||
));
|
||||
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/phid/constants');
|
||||
phutil_require_module('phabricator', 'applications/maniphest/query');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'applications/project/constants/status');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/affiliation');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/profile');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
phutil_require_module('phabricator', 'applications/project/transactions/search');
|
||||
phutil_require_module('phabricator', 'view/control/table');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhabricatorProjectTransactionSearch {
|
||||
private $projectPhids;
|
||||
private $documents;
|
||||
private $status;
|
||||
|
||||
public function __construct($project_phids) {
|
||||
if (is_array($project_phids)) {
|
||||
$this->projectPhids = $project_phids;
|
||||
} else {
|
||||
$this->projectPhids = array($project_phids);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
// search all open documents by default
|
||||
public function setSearchOptions($documents = '', $status = true) {
|
||||
$this->documents = $documents;
|
||||
$this->status = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function executeSearch() {
|
||||
$projects = $this->projectPhids;
|
||||
$on_documents = $this->documents;
|
||||
$with_status = $this->status;
|
||||
|
||||
$query = new PhabricatorSearchQuery();
|
||||
$query->setQuery('');
|
||||
$query->setParameter('project', $projects);
|
||||
$query->setParameter('type', $on_documents);
|
||||
$query->setParameter('open', $with_status);
|
||||
|
||||
$executor = new PhabricatorSearchMySQLExecutor();
|
||||
$results = $executor->executeSearch($query);
|
||||
return $results;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/search/execute/mysql');
|
||||
phutil_require_module('phabricator', 'applications/search/storage/query');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectTransactionSearch.php');
|
Loading…
Reference in a new issue