Support custom fields in "Order By" for Maniphest
Summary: Resolves T4659. This implements support for sorting tasks by custom fields. Some of this feels hacky in the way it's hooked up to the Maniphest search engine and task query. Test Plan: Queryed on a custom date field, with a small page size, and moved back and forth through the result set. Reviewers: #blessed_reviewers, epriestley Reviewed By: #blessed_reviewers, epriestley Subscribers: epriestley, Korvin Maniphest Tasks: T4659 Differential Revision: https://secure.phabricator.com/D10106
This commit is contained in:
@@ -12,6 +12,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
|
||||
private $afterID;
|
||||
private $beforeID;
|
||||
private $applicationSearchConstraints = array();
|
||||
private $applicationSearchOrders = array();
|
||||
private $internalPaging;
|
||||
|
||||
protected function getPagingColumn() {
|
||||
@@ -359,6 +360,32 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Order the results by an ApplicationSearch index.
|
||||
*
|
||||
* @param PhabricatorCustomField Field to which the index belongs.
|
||||
* @param PhabricatorCustomFieldIndexStorage Table where the index is stored.
|
||||
* @param bool True to sort ascending.
|
||||
* @return this
|
||||
* @task appsearch
|
||||
*/
|
||||
public function withApplicationSearchOrder(
|
||||
PhabricatorCustomField $field,
|
||||
PhabricatorCustomFieldIndexStorage $index,
|
||||
$ascending) {
|
||||
|
||||
$this->applicationSearchOrders[] = array(
|
||||
'key' => $field->getFieldKey(),
|
||||
'type' => $index->getIndexValueType(),
|
||||
'table' => $index->getTableName(),
|
||||
'index' => $index->getIndexKey(),
|
||||
'ascending' => $ascending,
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the query's primary object PHID column, for constructing
|
||||
* JOIN clauses. Normally (and by default) this is just `"phid"`, but if the
|
||||
@@ -535,7 +562,72 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->applicationSearchOrders as $key => $order) {
|
||||
$table = $order['table'];
|
||||
$alias = 'appsearch_order_'.$key;
|
||||
$index = $order['index'];
|
||||
$phid_column = $this->getApplicationSearchObjectPHIDColumn();
|
||||
|
||||
$joins[] = qsprintf(
|
||||
$conn_r,
|
||||
'JOIN %T %T ON %T.objectPHID = %Q
|
||||
AND %T.indexKey = %s',
|
||||
$table,
|
||||
$alias,
|
||||
$alias,
|
||||
$phid_column,
|
||||
$alias,
|
||||
$index);
|
||||
}
|
||||
|
||||
return implode(' ', $joins);
|
||||
}
|
||||
|
||||
protected function buildApplicationSearchOrders(
|
||||
AphrontDatabaseConnection $conn_r,
|
||||
$reverse) {
|
||||
|
||||
$orders = array();
|
||||
foreach ($this->applicationSearchOrders as $key => $order) {
|
||||
$alias = 'appsearch_order_'.$key;
|
||||
|
||||
if ($order['ascending'] xor $reverse) {
|
||||
$orders[] = qsprintf($conn_r, '%T.indexValue ASC', $alias);
|
||||
} else {
|
||||
$orders[] = qsprintf($conn_r, '%T.indexValue DESC', $alias);
|
||||
}
|
||||
}
|
||||
|
||||
return $orders;
|
||||
}
|
||||
|
||||
protected function buildApplicationSearchPagination(
|
||||
AphrontDatabaseConnection $conn_r,
|
||||
$cursor) {
|
||||
|
||||
// We have to get the current field values on the cursor object.
|
||||
$fields = PhabricatorCustomField::getObjectFields(
|
||||
$cursor,
|
||||
PhabricatorCustomField::ROLE_APPLICATIONSEARCH);
|
||||
$fields->setViewer($this->getViewer());
|
||||
$fields->readFieldsFromStorage($cursor);
|
||||
|
||||
$fields = mpull($fields->getFields(), null, 'getFieldKey');
|
||||
|
||||
$columns = array();
|
||||
foreach ($this->applicationSearchOrders as $key => $order) {
|
||||
$alias = 'appsearch_order_'.$key;
|
||||
|
||||
$field = idx($fields, $order['key']);
|
||||
|
||||
$columns[] = array(
|
||||
'name' => $alias.'.indexValue',
|
||||
'value' => $field->getValueForStorage(),
|
||||
'type' => $order['type'],
|
||||
);
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user