diff --git a/src/applications/people/query/PhabricatorPeopleSearchEngine.php b/src/applications/people/query/PhabricatorPeopleSearchEngine.php --- a/src/applications/people/query/PhabricatorPeopleSearchEngine.php +++ b/src/applications/people/query/PhabricatorPeopleSearchEngine.php @@ -11,45 +11,72 @@ return 'PhabricatorPeopleApplication'; } - public function getCustomFieldObject() { + public function newResultObject() { return new PhabricatorUser(); } - public function buildSavedQueryFromRequest(AphrontRequest $request) { - $saved = new PhabricatorSavedQuery(); - - $saved->setParameter('usernames', $request->getStrList('usernames')); - $saved->setParameter('nameLike', $request->getStr('nameLike')); - - $saved->setParameter( - 'isAdmin', - $this->readBoolFromRequest($request, 'isAdmin')); - - $saved->setParameter( - 'isDisabled', - $this->readBoolFromRequest($request, 'isDisabled')); - - $saved->setParameter( - 'isSystemAgent', - $this->readBoolFromRequest($request, 'isSystemAgent')); - - $saved->setParameter( - 'isMailingList', - $this->readBoolFromRequest($request, 'isMailingList')); - - $saved->setParameter( - 'needsApproval', - $this->readBoolFromRequest($request, 'needsApproval')); - - $saved->setParameter('createdStart', $request->getStr('createdStart')); - $saved->setParameter('createdEnd', $request->getStr('createdEnd')); - - $this->readCustomFieldsFromRequest($request, $saved); + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorSearchStringListField()) + ->setLabel(pht('Usernames')) + ->setKey('usernames') + ->setAliases(array('username')), + id(new PhabricatorSearchTextField()) + ->setLabel(pht('Name Contains')) + ->setKey('nameLike'), + id(new PhabricatorSearchThreeStateField()) + ->setLabel(pht('Administrators')) + ->setKey('isAdmin') + ->setOptions( + pht('(Show All)'), + pht('Show Only Administrators'), + pht('Hide Administrators')), + id(new PhabricatorSearchThreeStateField()) + ->setLabel(pht('Disabled')) + ->setKey('isDisabled') + ->setOptions( + pht('(Show All)'), + pht('Show Only Disabled Users'), + pht('Hide Disabled Users')), + id(new PhabricatorSearchThreeStateField()) + ->setLabel(pht('Bots')) + ->setKey('isSystemAgent') + ->setOptions( + pht('(Show All)'), + pht('Show Only Bots'), + pht('Hide Bots')), + id(new PhabricatorSearchThreeStateField()) + ->setLabel(pht('Mailing Lists')) + ->setKey('isMailingList') + ->setOptions( + pht('(Show All)'), + pht('Show Only Mailing Lists'), + pht('Hide Mailing Lists')), + id(new PhabricatorSearchThreeStateField()) + ->setLabel(pht('Needs Approval')) + ->setKey('needsApproval') + ->setOptions( + pht('(Show All)'), + pht('Show Only Unapproved Users'), + pht('Hide Unappproved Users')), + id(new PhabricatorSearchDateField()) + ->setKey('createdStart') + ->setLabel(pht('Joined After')), + id(new PhabricatorSearchDateField()) + ->setKey('createdEnd') + ->setLabel(pht('Joined Before')), + ); + } - return $saved; + protected function getDefaultFieldOrder() { + return array( + '...', + 'createdStart', + 'createdEnd', + ); } - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { + public function buildQueryFromParameters(array $map) { $query = id(new PhabricatorPeopleQuery()) ->needPrimaryEmail(true) ->needProfileImage(true); @@ -68,149 +95,45 @@ $query->withPHIDs(array($viewer->getPHID())); } - $usernames = $saved->getParameter('usernames', array()); - if ($usernames) { - $query->withUsernames($usernames); + if ($map['usernames']) { + $query->withUsernames($map['usernames']); } - $like = $saved->getParameter('nameLike'); - if ($like) { - $query->withNameLike($like); + if ($map['nameLike']) { + $query->withNameLike($map['nameLike']); } - $is_admin = $saved->getParameter('isAdmin'); - $is_disabled = $saved->getParameter('isDisabled'); - $is_system_agent = $saved->getParameter('isSystemAgent'); - $is_mailing_list = $saved->getParameter('isMailingList'); - $needs_approval = $saved->getParameter('needsApproval'); - - if ($is_admin !== null) { - $query->withIsAdmin($is_admin); + if ($map['isAdmin'] !== null) { + $query->withIsAdmin($map['isAdmin']); } - if ($is_disabled !== null) { - $query->withIsDisabled($is_disabled); + if ($map['isDisabled'] !== null) { + $query->withIsDisabled($map['isDisabled']); } - if ($is_system_agent !== null) { - $query->withIsSystemAgent($is_system_agent); + if ($map['isMailingList'] !== null) { + $query->withIsMailingList($map['isMailingList']); } - if ($is_mailing_list !== null) { - $query->withIsMailingList($is_mailing_list); + if ($map['isSystemAgent'] !== null) { + $query->withIsSystemAgent($map['isSystemAgent']); } - if ($needs_approval !== null) { - $query->withIsApproved(!$needs_approval); + if ($map['needsApproval'] !== null) { + $query->withIsApproved(!$map['needsApproval']); } - $start = $this->parseDateTime($saved->getParameter('createdStart')); - $end = $this->parseDateTime($saved->getParameter('createdEnd')); - - if ($start) { - $query->withDateCreatedAfter($start); + if ($map['createdStart']) { + $query->withDateCreatedAfter($map['createdStart']); } - if ($end) { - $query->withDateCreatedBefore($end); + if ($map['createdEnd']) { + $query->withDateCreatedBefore($map['createdEnd']); } - $this->applyCustomFieldsToQuery($query, $saved); - return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved) { - - $usernames = $saved->getParameter('usernames', array()); - $like = $saved->getParameter('nameLike'); - - $is_admin = $this->getBoolFromQuery($saved, 'isAdmin'); - $is_disabled = $this->getBoolFromQuery($saved, 'isDisabled'); - $is_system_agent = $this->getBoolFromQuery($saved, 'isSystemAgent'); - $is_mailing_list = $this->getBoolFromQuery($saved, 'isMailingList'); - $needs_approval = $this->getBoolFromQuery($saved, 'needsApproval'); - - $form - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('usernames') - ->setLabel(pht('Usernames')) - ->setValue(implode(', ', $usernames))) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('nameLike') - ->setLabel(pht('Name Contains')) - ->setValue($like)) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('isAdmin') - ->setLabel(pht('Administrators')) - ->setValue($is_admin) - ->setOptions( - array( - '' => pht('(Show All)'), - 'true' => pht('Show Only Administrators'), - 'false' => pht('Hide Administrators'), - ))) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('isDisabled') - ->setLabel(pht('Disabled')) - ->setValue($is_disabled) - ->setOptions( - array( - '' => pht('(Show All)'), - 'true' => pht('Show Only Disabled Users'), - 'false' => pht('Hide Disabled Users'), - ))) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('isSystemAgent') - ->setLabel(pht('Bots')) - ->setValue($is_system_agent) - ->setOptions( - array( - '' => pht('(Show All)'), - 'true' => pht('Show Only Bots'), - 'false' => pht('Hide Bots'), - ))) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('isMailingList') - ->setLabel(pht('Mailing Lists')) - ->setValue($is_mailing_list) - ->setOptions( - array( - '' => pht('(Show All)'), - 'true' => pht('Show Only Mailing Lists'), - 'false' => pht('Hide Mailing Lists'), - ))) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('needsApproval') - ->setLabel(pht('Needs Approval')) - ->setValue($needs_approval) - ->setOptions( - array( - '' => pht('(Show All)'), - 'true' => pht('Show Only Unapproved Users'), - 'false' => pht('Hide Unapproved Users'), - ))); - - $this->appendCustomFieldsToForm($form, $saved); - - $this->buildDateRange( - $form, - $saved, - 'createdStart', - pht('Joined After'), - 'createdEnd', - pht('Joined Before')); - } - protected function getURI($path) { return '/people/'.$path; } diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php --- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php +++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php @@ -200,13 +200,81 @@ $fields[] = $custom_field; } - return $fields; + $field_map = array(); + foreach ($fields as $field) { + $key = $field->getKey(); + if (isset($field_map[$key])) { + throw new Exception( + pht( + 'Two fields in this SearchEngine use the same key ("%s"), but '. + 'each field must use a unique key.', + $key)); + } + $field_map[$key] = $field; + } + + return $this->adjustFieldsForDisplay($field_map); + } + + private function adjustFieldsForDisplay(array $field_map) { + $order = $this->getDefaultFieldOrder(); + + $head_keys = array(); + $tail_keys = array(); + $seen_tail = false; + foreach ($order as $order_key) { + if ($order_key === '...') { + $seen_tail = true; + continue; + } + + if (!$seen_tail) { + $head_keys[] = $order_key; + } else { + $tail_keys[] = $order_key; + } + } + + $head = array_select_keys($field_map, $head_keys); + $body = array_diff_key($field_map, array_fuse($tail_keys)); + $tail = array_select_keys($field_map, $tail_keys); + + return $head + $body + $tail; } protected function buildCustomSearchFields() { throw new PhutilMethodNotImplementedException(); } + + /** + * Define the default display order for fields by returning a list of + * field keys. + * + * You can use the special key `...` to mean "all unspecified fields go + * here". This lets you easily put important fields at the top of the form, + * standard fields in the middle of the form, and less important fields at + * the bottom. + * + * For example, you might return a list like this: + * + * return array( + * 'authorPHIDs', + * 'reviewerPHIDs', + * '...', + * 'createdAfter', + * 'createdBefore', + * ); + * + * Any unspecified fields (including custom fields and fields added + * automatically by infrastruture) will be put in the middle. + * + * @return list Default ordering for field keys. + */ + protected function getDefaultFieldOrder() { + return array(); + } + public function getErrors() { return $this->errors; } @@ -1101,8 +1169,7 @@ return 'custom:'.$field->getFieldIndex(); } - - protected function buildCustomFieldSearchFields() { + private function buildCustomFieldSearchFields() { $list = $this->getCustomFieldList(); if (!$list) { return array();