1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-24 06:20:56 +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:
epriestley 2015-06-07 07:31:28 -07:00
parent 64b690f23f
commit 2492fef029
9 changed files with 171 additions and 115 deletions

View file

@ -2500,6 +2500,7 @@ phutil_register_library_map(array(
'PhabricatorSearchApplicationStorageEnginePanel' => 'applications/search/applicationpanel/PhabricatorSearchApplicationStorageEnginePanel.php', 'PhabricatorSearchApplicationStorageEnginePanel' => 'applications/search/applicationpanel/PhabricatorSearchApplicationStorageEnginePanel.php',
'PhabricatorSearchAttachController' => 'applications/search/controller/PhabricatorSearchAttachController.php', 'PhabricatorSearchAttachController' => 'applications/search/controller/PhabricatorSearchAttachController.php',
'PhabricatorSearchBaseController' => 'applications/search/controller/PhabricatorSearchBaseController.php', 'PhabricatorSearchBaseController' => 'applications/search/controller/PhabricatorSearchBaseController.php',
'PhabricatorSearchCheckboxesField' => 'applications/search/field/PhabricatorSearchCheckboxesField.php',
'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php', 'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php',
'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php', 'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php',
'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php', 'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php',
@ -2523,6 +2524,7 @@ phutil_register_library_map(array(
'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php', 'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
'PhabricatorSearchOrderController' => 'applications/search/controller/PhabricatorSearchOrderController.php', 'PhabricatorSearchOrderController' => 'applications/search/controller/PhabricatorSearchOrderController.php',
'PhabricatorSearchPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorSearchPreferencesSettingsPanel.php', 'PhabricatorSearchPreferencesSettingsPanel' => 'applications/settings/panel/PhabricatorSearchPreferencesSettingsPanel.php',
'PhabricatorSearchProjectsField' => 'applications/search/field/PhabricatorSearchProjectsField.php',
'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php', 'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php',
'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php', 'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php', 'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
@ -6002,6 +6004,7 @@ phutil_register_library_map(array(
'PhabricatorSearchApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel', 'PhabricatorSearchApplicationStorageEnginePanel' => 'PhabricatorApplicationConfigurationPanel',
'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchBaseController' => 'PhabricatorController', 'PhabricatorSearchBaseController' => 'PhabricatorController',
'PhabricatorSearchCheckboxesField' => 'PhabricatorSearchField',
'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorSearchController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchDAO' => 'PhabricatorLiskDAO', 'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
@ -6023,6 +6026,7 @@ phutil_register_library_map(array(
'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow', 'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorSearchOrderController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchOrderController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchPreferencesSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorSearchPreferencesSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorSearchProjectsField' => 'PhabricatorSearchTokenizerField',
'PhabricatorSearchResultView' => 'AphrontView', 'PhabricatorSearchResultView' => 'AphrontView',
'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
'PhabricatorSearchSpacesField' => 'PhabricatorSearchTokenizerField', 'PhabricatorSearchSpacesField' => 'PhabricatorSearchTokenizerField',

View file

@ -72,20 +72,7 @@ final class PhabricatorPasteQuery
} }
protected function loadPage() { protected function loadPage() {
$table = new PhabricatorPaste(); return $this->loadStandardPage(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;
} }
protected function didFilterPage(array $pastes) { protected function didFilterPage(array $pastes) {
@ -103,49 +90,49 @@ final class PhabricatorPasteQuery
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn); $where = parent::buildWhereClauseParts($conn);
if ($this->ids) { if ($this->ids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'id IN (%Ld)', 'id IN (%Ld)',
$this->ids); $this->ids);
} }
if ($this->phids) { if ($this->phids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'phid IN (%Ls)', 'phid IN (%Ls)',
$this->phids); $this->phids);
} }
if ($this->authorPHIDs) { if ($this->authorPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'authorPHID IN (%Ls)', 'authorPHID IN (%Ls)',
$this->authorPHIDs); $this->authorPHIDs);
} }
if ($this->parentPHIDs) { if ($this->parentPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'parentPHID IN (%Ls)', 'parentPHID IN (%Ls)',
$this->parentPHIDs); $this->parentPHIDs);
} }
if ($this->languages) { if ($this->languages !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'language IN (%Ls)', 'language IN (%Ls)',
$this->languages); $this->languages);
} }
if ($this->dateCreatedAfter) { if ($this->dateCreatedAfter !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'dateCreated >= %d', 'dateCreated >= %d',
$this->dateCreatedAfter); $this->dateCreatedAfter);
} }
if ($this->dateCreatedBefore) { if ($this->dateCreatedBefore !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'dateCreated <= %d', 'dateCreated <= %d',

View file

@ -54,22 +54,7 @@ final class PholioMockQuery
} }
protected function loadPage() { protected function loadPage() {
$table = new PholioMock(); $mocks = $this->loadStandardPage(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);
if ($mocks && $this->needImages) { if ($mocks && $this->needImages) {
self::loadImages($this->getViewer(), $mocks, $this->needInlineComments); self::loadImages($this->getViewer(), $mocks, $this->needInlineComments);
@ -86,40 +71,38 @@ final class PholioMockQuery
return $mocks; return $mocks;
} }
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = array(); $where = parent::buildWhereClauseParts($conn);
$where[] = $this->buildWhereClauseParts($conn_r);
if ($this->ids !== null) { if ($this->ids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'mock.id IN (%Ld)', 'mock.id IN (%Ld)',
$this->ids); $this->ids);
} }
if ($this->phids !== null) { if ($this->phids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'mock.phid IN (%Ls)', 'mock.phid IN (%Ls)',
$this->phids); $this->phids);
} }
if ($this->authorPHIDs !== null) { if ($this->authorPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'mock.authorPHID in (%Ls)', 'mock.authorPHID in (%Ls)',
$this->authorPHIDs); $this->authorPHIDs);
} }
if ($this->statuses !== null) { if ($this->statuses !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn_r, $conn,
'mock.status IN (%Ls)', 'mock.status IN (%Ls)',
$this->statuses); $this->statuses);
} }
return $this->formatWhereClause($where); return $where;
} }
public static function loadImages( public static function loadImages(

View file

@ -10,86 +10,42 @@ final class PholioMockSearchEngine extends PhabricatorApplicationSearchEngine {
return 'PhabricatorPholioApplication'; return 'PhabricatorPholioApplication';
} }
public function buildSavedQueryFromRequest(AphrontRequest $request) { public function newResultObject() {
$saved = new PhabricatorSavedQuery(); return new PholioMock();
$saved->setParameter(
'authorPHIDs',
$this->readUsersFromRequest($request, 'authors'));
$saved->setParameter(
'projects',
$this->readProjectsFromRequest($request, 'projects'));
$saved->setParameter(
'statuses',
$request->getStrList('status'));
return $saved;
} }
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()) $query = id(new PholioMockQuery())
->needCoverFiles(true) ->needCoverFiles(true)
->needImages(true) ->needImages(true)
->needTokenCounts(true); ->needTokenCounts(true);
$datasource = id(new PhabricatorPeopleUserFunctionDatasource()) if ($map['authorPHIDs']) {
->setViewer($this->requireViewer()); $query->withAuthorPHIDs($map['authorPHIDs']);
$author_phids = $saved->getParameter('authorPHIDs', array());
$author_phids = $datasource->evaluateTokens($author_phids);
if ($author_phids) {
$query->withAuthorPHIDs($author_phids);
} }
$statuses = $saved->getParameter('statuses', array()); if ($map['statuses']) {
if ($statuses) { $query->withStatuses($map['statuses']);
$query->withStatuses($statuses);
} }
$this->setQueryProjects($query, $saved);
return $query; 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) { protected function getURI($path) {
return '/pholio/'.$path; return '/pholio/'.$path;
} }

View file

@ -13,6 +13,9 @@ final class PholioMock extends PholioDAO
const MARKUP_FIELD_DESCRIPTION = 'markup:description'; const MARKUP_FIELD_DESCRIPTION = 'markup:description';
const STATUS_OPEN = 'open';
const STATUS_CLOSED = 'closed';
protected $authorPHID; protected $authorPHID;
protected $viewPolicy; protected $viewPolicy;
protected $editPolicy; protected $editPolicy;
@ -41,7 +44,7 @@ final class PholioMock extends PholioDAO
return id(new PholioMock()) return id(new PholioMock())
->setAuthorPHID($actor->getPHID()) ->setAuthorPHID($actor->getPHID())
->attachImages(array()) ->attachImages(array())
->setStatus('open') ->setStatus(self::STATUS_OPEN)
->setViewPolicy($view_policy) ->setViewPolicy($view_policy)
->setEditPolicy($edit_policy); ->setEditPolicy($edit_policy);
} }
@ -159,8 +162,8 @@ final class PholioMock extends PholioDAO
public function getStatuses() { public function getStatuses() {
$options = array(); $options = array();
$options['open'] = pht('Open'); $options[self::STATUS_OPEN] = pht('Open');
$options['closed'] = pht('Closed'); $options[self::STATUS_CLOSED] = pht('Closed');
return $options; return $options;
} }

View file

@ -113,6 +113,14 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $query; return $query;
} }
if ($object instanceof PhabricatorProjectInterface) {
if (!empty($parameters['projectPHIDs'])) {
$query->withEdgeLogicConstraints(
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST,
$parameters['projectPHIDs']);
}
}
if ($object instanceof PhabricatorSpacesInterface) { if ($object instanceof PhabricatorSpacesInterface) {
if (!empty($parameters['spacePHIDs'])) { if (!empty($parameters['spacePHIDs'])) {
$query->withSpacePHIDs($parameters['spacePHIDs']); $query->withSpacePHIDs($parameters['spacePHIDs']);
@ -168,6 +176,13 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
return $fields; return $fields;
} }
if ($object instanceof PhabricatorProjectInterface) {
$fields[] = id(new PhabricatorSearchProjectsField())
->setKey('projectPHIDs')
->setAliases(array('project', 'projects'))
->setLabel(pht('Projects'));
}
if ($object instanceof PhabricatorSpacesInterface) { if ($object instanceof PhabricatorSpacesInterface) {
if (PhabricatorSpacesNamespaceQuery::getSpacesExist()) { if (PhabricatorSpacesNamespaceQuery::getSpacesExist()) {
$fields[] = id(new PhabricatorSearchSpacesField()) $fields[] = id(new PhabricatorSearchSpacesField())

View file

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

View file

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

View file

@ -76,6 +76,24 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
return $this->beforeID; 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. * Get the viewer for making cursor paging queries.