mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
Move Pholio to SearchFields
Summary: Ref T8441. Ref T7715. - Update PholioSearchEngine. - Automatically add project fields. - Update Paste to support project search. - Simplify common Query class construction. Test Plan: - Searched for pastes. - Searched for mocks. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7715, T8441 Differential Revision: https://secure.phabricator.com/D13174
This commit is contained in:
parent
64b690f23f
commit
2492fef029
9 changed files with 171 additions and 115 deletions
|
@ -2500,6 +2500,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSearchApplicationStorageEnginePanel' => 'applications/search/applicationpanel/PhabricatorSearchApplicationStorageEnginePanel.php',
|
||||
'PhabricatorSearchAttachController' => 'applications/search/controller/PhabricatorSearchAttachController.php',
|
||||
'PhabricatorSearchBaseController' => 'applications/search/controller/PhabricatorSearchBaseController.php',
|
||||
'PhabricatorSearchCheckboxesField' => 'applications/search/field/PhabricatorSearchCheckboxesField.php',
|
||||
'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php',
|
||||
'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php',
|
||||
'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php',
|
||||
|
@ -2523,6 +2524,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
|
||||
'PhabricatorSearchOrderController' => 'applications/search/controller/PhabricatorSearchOrderController.php',
|
||||
'PhabricatorSearchPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorSearchPreferencesSettingsPanel.php',
|
||||
'PhabricatorSearchProjectsField' => 'applications/search/field/PhabricatorSearchProjectsField.php',
|
||||
'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php',
|
||||
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
|
||||
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
|
||||
|
@ -6002,6 +6004,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSearchApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel',
|
||||
'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
|
||||
'PhabricatorSearchBaseController' => 'PhabricatorController',
|
||||
'PhabricatorSearchCheckboxesField' => 'PhabricatorSearchField',
|
||||
'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
|
||||
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
|
||||
|
@ -6023,6 +6026,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorSearchOrderController' => 'PhabricatorSearchBaseController',
|
||||
'PhabricatorSearchPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorSearchProjectsField' => 'PhabricatorSearchTokenizerField',
|
||||
'PhabricatorSearchResultView' => 'AphrontView',
|
||||
'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
|
||||
'PhabricatorSearchSpacesField' => 'PhabricatorSearchTokenizerField',
|
||||
|
|
|
@ -72,20 +72,7 @@ final class PhabricatorPasteQuery
|
|||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new PhabricatorPaste();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn_r,
|
||||
'SELECT paste.* FROM %T paste %Q %Q %Q',
|
||||
$table->getTableName(),
|
||||
$this->buildWhereClause($conn_r),
|
||||
$this->buildOrderClause($conn_r),
|
||||
$this->buildLimitClause($conn_r));
|
||||
|
||||
$pastes = $table->loadAllFromArray($data);
|
||||
|
||||
return $pastes;
|
||||
return $this->loadStandardPage(new PhabricatorPaste());
|
||||
}
|
||||
|
||||
protected function didFilterPage(array $pastes) {
|
||||
|
@ -103,49 +90,49 @@ final class PhabricatorPasteQuery
|
|||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if ($this->ids) {
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids) {
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->authorPHIDs) {
|
||||
if ($this->authorPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'authorPHID IN (%Ls)',
|
||||
$this->authorPHIDs);
|
||||
}
|
||||
|
||||
if ($this->parentPHIDs) {
|
||||
if ($this->parentPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'parentPHID IN (%Ls)',
|
||||
$this->parentPHIDs);
|
||||
}
|
||||
|
||||
if ($this->languages) {
|
||||
if ($this->languages !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'language IN (%Ls)',
|
||||
$this->languages);
|
||||
}
|
||||
|
||||
if ($this->dateCreatedAfter) {
|
||||
if ($this->dateCreatedAfter !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'dateCreated >= %d',
|
||||
$this->dateCreatedAfter);
|
||||
}
|
||||
|
||||
if ($this->dateCreatedBefore) {
|
||||
if ($this->dateCreatedBefore !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn,
|
||||
'dateCreated <= %d',
|
||||
|
|
|
@ -54,22 +54,7 @@ final class PholioMockQuery
|
|||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new PholioMock();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn_r,
|
||||
'%Q FROM %T mock %Q %Q %Q %Q %Q %Q',
|
||||
$this->buildSelectClause($conn_r),
|
||||
$table->getTableName(),
|
||||
$this->buildJoinClause($conn_r),
|
||||
$this->buildWhereClause($conn_r),
|
||||
$this->buildGroupClause($conn_r),
|
||||
$this->buildOrderClause($conn_r),
|
||||
$this->buildHavingClause($conn_r),
|
||||
$this->buildLimitClause($conn_r));
|
||||
|
||||
$mocks = $table->loadAllFromArray($data);
|
||||
$mocks = $this->loadStandardPage(new PholioMock());
|
||||
|
||||
if ($mocks && $this->needImages) {
|
||||
self::loadImages($this->getViewer(), $mocks, $this->needInlineComments);
|
||||
|
@ -86,40 +71,38 @@ final class PholioMockQuery
|
|||
return $mocks;
|
||||
}
|
||||
|
||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
||||
$where = array();
|
||||
|
||||
$where[] = $this->buildWhereClauseParts($conn_r);
|
||||
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||
$where = parent::buildWhereClauseParts($conn);
|
||||
|
||||
if ($this->ids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'mock.id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->phids !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'mock.phid IN (%Ls)',
|
||||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->authorPHIDs !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'mock.authorPHID in (%Ls)',
|
||||
$this->authorPHIDs);
|
||||
}
|
||||
|
||||
if ($this->statuses !== null) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
$conn,
|
||||
'mock.status IN (%Ls)',
|
||||
$this->statuses);
|
||||
}
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
return $where;
|
||||
}
|
||||
|
||||
public static function loadImages(
|
||||
|
|
|
@ -10,86 +10,42 @@ final class PholioMockSearchEngine extends PhabricatorApplicationSearchEngine {
|
|||
return 'PhabricatorPholioApplication';
|
||||
}
|
||||
|
||||
public function buildSavedQueryFromRequest(AphrontRequest $request) {
|
||||
$saved = new PhabricatorSavedQuery();
|
||||
|
||||
$saved->setParameter(
|
||||
'authorPHIDs',
|
||||
$this->readUsersFromRequest($request, 'authors'));
|
||||
|
||||
$saved->setParameter(
|
||||
'projects',
|
||||
$this->readProjectsFromRequest($request, 'projects'));
|
||||
|
||||
$saved->setParameter(
|
||||
'statuses',
|
||||
$request->getStrList('status'));
|
||||
|
||||
return $saved;
|
||||
public function newResultObject() {
|
||||
return new PholioMock();
|
||||
}
|
||||
|
||||
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
|
||||
public function buildCustomSearchFields() {
|
||||
return array(
|
||||
id(new PhabricatorSearchUsersField())
|
||||
->setKey('authorPHIDs')
|
||||
->setAliases(array('authors'))
|
||||
->setLabel(pht('Authors')),
|
||||
id(new PhabricatorSearchCheckboxesField())
|
||||
->setKey('statuses')
|
||||
->setLabel(pht('Status'))
|
||||
->setOptions(
|
||||
id(new PholioMock())
|
||||
->getStatuses()),
|
||||
);
|
||||
}
|
||||
|
||||
public function buildQueryFromParameters(array $map) {
|
||||
$query = id(new PholioMockQuery())
|
||||
->needCoverFiles(true)
|
||||
->needImages(true)
|
||||
->needTokenCounts(true);
|
||||
|
||||
$datasource = id(new PhabricatorPeopleUserFunctionDatasource())
|
||||
->setViewer($this->requireViewer());
|
||||
|
||||
$author_phids = $saved->getParameter('authorPHIDs', array());
|
||||
$author_phids = $datasource->evaluateTokens($author_phids);
|
||||
if ($author_phids) {
|
||||
$query->withAuthorPHIDs($author_phids);
|
||||
if ($map['authorPHIDs']) {
|
||||
$query->withAuthorPHIDs($map['authorPHIDs']);
|
||||
}
|
||||
|
||||
$statuses = $saved->getParameter('statuses', array());
|
||||
if ($statuses) {
|
||||
$query->withStatuses($statuses);
|
||||
if ($map['statuses']) {
|
||||
$query->withStatuses($map['statuses']);
|
||||
}
|
||||
|
||||
$this->setQueryProjects($query, $saved);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function buildSearchForm(
|
||||
AphrontFormView $form,
|
||||
PhabricatorSavedQuery $saved_query) {
|
||||
|
||||
$author_phids = $saved_query->getParameter('authorPHIDs', array());
|
||||
$projects = $saved_query->getParameter('projects', array());
|
||||
|
||||
$statuses = array(
|
||||
'' => pht('Any Status'),
|
||||
'closed' => pht('Closed'),
|
||||
'open' => pht('Open'),
|
||||
);
|
||||
|
||||
$status = $saved_query->getParameter('statuses', array());
|
||||
$status = head($status);
|
||||
|
||||
$form
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new PhabricatorPeopleUserFunctionDatasource())
|
||||
->setName('authors')
|
||||
->setLabel(pht('Authors'))
|
||||
->setValue($author_phids))
|
||||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setDatasource(new PhabricatorProjectLogicalDatasource())
|
||||
->setName('projects')
|
||||
->setLabel(pht('Projects'))
|
||||
->setValue($projects))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
->setLabel(pht('Status'))
|
||||
->setName('status')
|
||||
->setOptions($statuses)
|
||||
->setValue($status));
|
||||
}
|
||||
|
||||
protected function getURI($path) {
|
||||
return '/pholio/'.$path;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ final class PholioMock extends PholioDAO
|
|||
|
||||
const MARKUP_FIELD_DESCRIPTION = 'markup:description';
|
||||
|
||||
const STATUS_OPEN = 'open';
|
||||
const STATUS_CLOSED = 'closed';
|
||||
|
||||
protected $authorPHID;
|
||||
protected $viewPolicy;
|
||||
protected $editPolicy;
|
||||
|
@ -41,7 +44,7 @@ final class PholioMock extends PholioDAO
|
|||
return id(new PholioMock())
|
||||
->setAuthorPHID($actor->getPHID())
|
||||
->attachImages(array())
|
||||
->setStatus('open')
|
||||
->setStatus(self::STATUS_OPEN)
|
||||
->setViewPolicy($view_policy)
|
||||
->setEditPolicy($edit_policy);
|
||||
}
|
||||
|
@ -159,8 +162,8 @@ final class PholioMock extends PholioDAO
|
|||
|
||||
public function getStatuses() {
|
||||
$options = array();
|
||||
$options['open'] = pht('Open');
|
||||
$options['closed'] = pht('Closed');
|
||||
$options[self::STATUS_OPEN] = pht('Open');
|
||||
$options[self::STATUS_CLOSED] = pht('Closed');
|
||||
return $options;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,14 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
|
|||
return $query;
|
||||
}
|
||||
|
||||
if ($object instanceof PhabricatorProjectInterface) {
|
||||
if (!empty($parameters['projectPHIDs'])) {
|
||||
$query->withEdgeLogicConstraints(
|
||||
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
|
||||
$parameters['projectPHIDs']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($object instanceof PhabricatorSpacesInterface) {
|
||||
if (!empty($parameters['spacePHIDs'])) {
|
||||
$query->withSpacePHIDs($parameters['spacePHIDs']);
|
||||
|
@ -168,6 +176,13 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
|
|||
return $fields;
|
||||
}
|
||||
|
||||
if ($object instanceof PhabricatorProjectInterface) {
|
||||
$fields[] = id(new PhabricatorSearchProjectsField())
|
||||
->setKey('projectPHIDs')
|
||||
->setAliases(array('project', 'projects'))
|
||||
->setLabel(pht('Projects'));
|
||||
}
|
||||
|
||||
if ($object instanceof PhabricatorSpacesInterface) {
|
||||
if (PhabricatorSpacesNamespaceQuery::getSpacesExist()) {
|
||||
$fields[] = id(new PhabricatorSearchSpacesField())
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSearchCheckboxesField
|
||||
extends PhabricatorSearchField {
|
||||
|
||||
private $options;
|
||||
|
||||
public function setOptions(array $options) {
|
||||
$this->options = $options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getOptions() {
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
protected function getDefaultValue() {
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function getValueFromRequest(AphrontRequest $request, $key) {
|
||||
return $this->getListFromRequest($request, $key);
|
||||
}
|
||||
|
||||
protected function newControl() {
|
||||
$value = array_fuse($this->getValue());
|
||||
|
||||
$control = new AphrontFormCheckboxControl();
|
||||
foreach ($this->getOptions() as $key => $option) {
|
||||
$control->addCheckbox(
|
||||
$this->getKey().'[]',
|
||||
$key,
|
||||
$option,
|
||||
isset($value[$key]));
|
||||
}
|
||||
|
||||
return $control;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorSearchProjectsField
|
||||
extends PhabricatorSearchTokenizerField {
|
||||
|
||||
protected function getDefaultValue() {
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function newDatasource() {
|
||||
return new PhabricatorProjectLogicalDatasource();
|
||||
}
|
||||
|
||||
protected function getValueFromRequest(AphrontRequest $request, $key) {
|
||||
$list = $this->getListFromRequest($request, $key);
|
||||
|
||||
$phids = array();
|
||||
$slugs = array();
|
||||
$project_type = PhabricatorProjectProjectPHIDType::TYPECONST;
|
||||
foreach ($list as $item) {
|
||||
$type = phid_get_type($item);
|
||||
if ($type == $project_type) {
|
||||
$phids[] = $item;
|
||||
} else {
|
||||
if (PhabricatorTypeaheadDatasource::isFunctionToken($item)) {
|
||||
// If this is a function, pass it through unchanged; we'll evaluate
|
||||
// it later.
|
||||
$phids[] = $item;
|
||||
} else {
|
||||
$slugs[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($slugs) {
|
||||
$projects = id(new PhabricatorProjectQuery())
|
||||
->setViewer($this->requireViewer())
|
||||
->withSlugs($slugs)
|
||||
->execute();
|
||||
foreach ($projects as $project) {
|
||||
$phids[] = $project->getPHID();
|
||||
}
|
||||
$phids = array_unique($phids);
|
||||
}
|
||||
|
||||
return $phids;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -76,6 +76,24 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
|
|||
return $this->beforeID;
|
||||
}
|
||||
|
||||
public function loadStandardPage(PhabricatorLiskDAO $table) {
|
||||
$conn = $table->establishConnection('r');
|
||||
|
||||
$rows = queryfx_all(
|
||||
$conn,
|
||||
'%Q FROM %T %Q %Q %Q %Q %Q %Q %Q',
|
||||
$this->buildSelectClause($conn),
|
||||
$table->getTableName(),
|
||||
(string)$this->getPrimaryTableAlias(),
|
||||
$this->buildJoinClause($conn),
|
||||
$this->buildWhereClause($conn),
|
||||
$this->buildGroupClause($conn),
|
||||
$this->buildHavingClause($conn),
|
||||
$this->buildOrderClause($conn),
|
||||
$this->buildLimitClause($conn));
|
||||
|
||||
return $table->loadAllFromArray($rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the viewer for making cursor paging queries.
|
||||
|
|
Loading…
Reference in a new issue