diff --git a/src/applications/flag/query/PhabricatorFlagQuery.php b/src/applications/flag/query/PhabricatorFlagQuery.php index db51b50360..58b1bc4609 100644 --- a/src/applications/flag/query/PhabricatorFlagQuery.php +++ b/src/applications/flag/query/PhabricatorFlagQuery.php @@ -1,138 +1,163 @@ ownerPHIDs = $owner_phids; return $this; } public function withTypes(array $types) { $this->types = $types; return $this; } public function withObjectPHIDs(array $object_phids) { $this->objectPHIDs = $object_phids; return $this; } public function withColors(array $colors) { $this->colors = $colors; return $this; } + /** + * Note this is done in php and not in mySQL, which means its inappropriate + * for large datasets. Pragmatically, this is fine for user flags which are + * typically well under 100 flags per user. + */ + public function setGroupBy($group) { + $this->groupBy = $group; + return $this; + } + public function needHandles($need) { $this->needHandles = $need; return $this; } public function needObjects($need) { $this->needObjects = $need; return $this; } public static function loadUserFlag(PhabricatorUser $user, $object_phid) { // Specifying the type in the query allows us to use a key. return id(new PhabricatorFlagQuery()) ->setViewer($user) ->withOwnerPHIDs(array($user->getPHID())) ->withTypes(array(phid_get_type($object_phid))) ->withObjectPHIDs(array($object_phid)) ->executeOne(); } public function loadPage() { $table = new PhabricatorFlag(); $conn_r = $table->establishConnection('r'); $data = queryfx_all( $conn_r, 'SELECT * FROM %T flag %Q %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); return $table->loadAllFromArray($data); } public function willFilterPage(array $flags) { if ($this->needObjects) { $objects = id(new PhabricatorObjectQuery()) ->setViewer($this->getViewer()) ->withPHIDs(mpull($flags, 'getObjectPHID')) ->execute(); $objects = mpull($objects, null, 'getPHID'); foreach ($flags as $key => $flag) { $object = idx($objects, $flag->getObjectPHID()); if ($object) { $flags[$key]->attachObject($object); } else { unset($flags[$key]); } } } if ($this->needHandles) { $handles = id(new PhabricatorHandleQuery()) ->setViewer($this->getViewer()) ->withPHIDs(mpull($flags, 'getObjectPHID')) ->execute(); foreach ($flags as $flag) { $flag->attachHandle($handles[$flag->getObjectPHID()]); } } + switch ($this->groupBy) { + case self::GROUP_COLOR: + $flags = msort($flags, 'getColor'); + break; + case self::GROUP_NONE: + break; + default: + throw new Exception("Unknown groupBy parameter: $this->groupBy"); + break; + } + return $flags; } private function buildWhereClause($conn_r) { $where = array(); if ($this->ownerPHIDs) { $where[] = qsprintf( $conn_r, 'flag.ownerPHID IN (%Ls)', $this->ownerPHIDs); } if ($this->types) { $where[] = qsprintf( $conn_r, 'flag.type IN (%Ls)', $this->types); } if ($this->objectPHIDs) { $where[] = qsprintf( $conn_r, 'flag.objectPHID IN (%Ls)', $this->objectPHIDs); } if ($this->colors) { $where[] = qsprintf( $conn_r, 'flag.color IN (%Ld)', $this->colors); } $where[] = $this->buildPagingClause($conn_r); return $this->formatWhereClause($where); } } diff --git a/src/applications/flag/query/PhabricatorFlagSearchEngine.php b/src/applications/flag/query/PhabricatorFlagSearchEngine.php index acca9b5d71..6647db4236 100644 --- a/src/applications/flag/query/PhabricatorFlagSearchEngine.php +++ b/src/applications/flag/query/PhabricatorFlagSearchEngine.php @@ -1,62 +1,82 @@ setParameter('colors', $request->getArr('colors')); + $saved->setParameter('group', $request->getStr('group')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhabricatorFlagQuery()) ->needHandles(true) ->withOwnerPHIDs(array($this->requireViewer()->getPHID())); $colors = $saved->getParameter('colors'); if ($colors) { $query->withColors($colors); } + $group = $saved->getParameter('group'); + $options = $this->getGroupOptions(); + if ($group && isset($options[$group])) { + $query->setGroupBy($group); + } return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { - $form->appendChild( - id(new PhabricatorFlagSelectControl()) + $form + ->appendChild( + id(new PhabricatorFlagSelectControl()) ->setName('colors') ->setLabel(pht('Colors')) - ->setValue($saved_query->getParameter('colors', array()))); + ->setValue($saved_query->getParameter('colors', array()))) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setName('group') + ->setLabel(pht('Group By')) + ->setValue($saved_query->getParameter('group')) + ->setOptions($this->getGroupOptions())); } protected function getURI($path) { return '/flag/'.$path; } public function getBuiltinQueryNames() { $names = array( 'all' => pht('Flagged'), ); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'all': return $query; } return parent::buildSavedQueryFromBuiltin($query_key); } + private function getGroupOptions() { + return array( + PhabricatorFlagQuery::GROUP_NONE => pht('None'), + PhabricatorFlagQuery::GROUP_COLOR => pht('Color'), + ); + } + }