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',
'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',

View file

@ -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',

View file

@ -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(

View file

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

View file

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

View file

@ -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())

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