diff --git a/src/applications/flag/query/PhabricatorFlagQuery.php b/src/applications/flag/query/PhabricatorFlagQuery.php index 1edeedc0c6..238562b666 100644 --- a/src/applications/flag/query/PhabricatorFlagQuery.php +++ b/src/applications/flag/query/PhabricatorFlagQuery.php @@ -1,194 +1,207 @@ viewer = $viewer; return $this; } public function withOwnerPHIDs(array $owner_phids) { $this->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 withColor($color) { + $this->color = $color; + return $this; + } + public function withOrder($order) { $this->order = $order; return $this; } public function needHandles($need) { $this->needHandles = $need; return $this; } public function needObjects($need) { $this->needObjects = $need; return $this; } public function setLimit($limit) { $this->limit = $limit; return $this; } public function setOffset($offset) { $this->offset = $offset; 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 PhabricatorFlag())->loadOneWhere( 'ownerPHID = %s AND type = %s AND objectPHID = %s', $user->getPHID(), phid_get_type($object_phid), $object_phid); } public function execute() { $table = new PhabricatorFlag(); $conn_r = $table->establishConnection('r'); $where = $this->buildWhereClause($conn_r); $limit = $this->buildLimitClause($conn_r); $order = $this->buildOrderClause($conn_r); $data = queryfx_all( $conn_r, 'SELECT * FROM %T flag %Q %Q %Q', $table->getTableName(), $where, $order, $limit); $flags = $table->loadAllFromArray($data); if ($this->needHandles || $this->needObjects) { $phids = ipull($data, 'objectPHID'); $query = new PhabricatorObjectHandleData($phids); $query->setViewer($this->viewer); if ($this->needHandles) { $handles = $query->loadHandles(); foreach ($flags as $flag) { $handle = idx($handles, $flag->getObjectPHID()); if ($handle) { $flag->attachHandle($handle); } } } if ($this->needObjects) { $objects = $query->loadObjects(); foreach ($flags as $flag) { $object = idx($objects, $flag->getObjectPHID()); if ($object) { $flag->attachObject($object); } } } } 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 (strlen($this->color)) { + $where[] = qsprintf( + $conn_r, + 'flag.color = %d', + $this->color); + } + if ($where) { return 'WHERE ('.implode(') AND (', $where).')'; } else { return ''; } } private function buildOrderClause($conn_r) { return qsprintf($conn_r, 'ORDER BY %Q', $this->getOrderColumn($conn_r)); } private function getOrderColumn($conn_r) { switch ($this->order) { case self::ORDER_ID: return 'id DESC'; break; case self::ORDER_COLOR: return 'color ASC'; break; case self::ORDER_OBJECT: return 'type DESC'; break; case self::ORDER_REASON: return 'reasonPHID DESC'; break; default: throw new Exception("Unknown order {$this->order}!"); break; } } private function buildLimitClause($conn_r) { if ($this->limit && $this->offset) { return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, $this->limit); } else if ($this->limit) { return qsprintf($conn_r, 'LIMIT %d', $this->limit); } else if ($this->offset) { return qsprintf($conn_r, 'LIMIT %d, %d', $this->offset, PHP_INT_MAX); } else { return ''; } } } diff --git a/src/applications/macro/query/PhabricatorMacroQuery.php b/src/applications/macro/query/PhabricatorMacroQuery.php index f5647e6efc..da8f7d9a13 100644 --- a/src/applications/macro/query/PhabricatorMacroQuery.php +++ b/src/applications/macro/query/PhabricatorMacroQuery.php @@ -1,183 +1,217 @@ pht('Active Macros'), self::STATUS_DISABLED => pht('Disabled Macros'), self::STATUS_ANY => pht('Active and Disabled Macros'), ); } + public static function getFlagColorsOptions() { + + $options = array('-1' => pht('(No Filtering)')); + + foreach (PhabricatorFlagColor::getColorNameMap() as $color => $name) { + $options[$color] = $name; + } + + return $options; + } + public function withIDs(array $ids) { $this->ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withAuthorPHIDs(array $authors) { $this->authors = $authors; return $this; } public function withNameLike($name) { $this->nameLike = $name; return $this; } public function withNames(array $names) { $this->names = $names; return $this; } public function withStatus($status) { $this->status = $status; return $this; } public function withDateCreatedBefore($date_created_before) { $this->dateCreatedBefore = $date_created_before; return $this; } public function withDateCreatedAfter($date_created_after) { $this->dateCreatedAfter = $date_created_after; return $this; } + public function withFlagColor($flag_color) { + $this->flagColor = $flag_color; + return $this; + } + protected function loadPage() { $macro_table = new PhabricatorFileImageMacro(); $conn = $macro_table->establishConnection('r'); $rows = queryfx_all( $conn, 'SELECT m.* FROM %T m %Q %Q %Q', $macro_table->getTableName(), $this->buildWhereClause($conn), $this->buildOrderClause($conn), $this->buildLimitClause($conn)); return $macro_table->loadAllFromArray($rows); } protected function buildWhereClause(AphrontDatabaseConnection $conn) { $where = array(); if ($this->ids) { $where[] = qsprintf( $conn, 'm.id IN (%Ld)', $this->ids); } if ($this->phids) { $where[] = qsprintf( $conn, 'm.phid IN (%Ls)', $this->phids); } if ($this->authors) { $where[] = qsprintf( $conn, 'm.authorPHID IN (%Ls)', $this->authors); } if ($this->nameLike) { $where[] = qsprintf( $conn, 'm.name LIKE %~', $this->nameLike); } if ($this->names) { $where[] = qsprintf( $conn, 'm.name IN (%Ls)', $this->names); } switch ($this->status) { case self::STATUS_ACTIVE: $where[] = qsprintf( $conn, 'm.isDisabled = 0'); break; case self::STATUS_DISABLED: $where[] = qsprintf( $conn, 'm.isDisabled = 1'); break; case self::STATUS_ANY: break; default: throw new Exception("Unknown status '{$this->status}'!"); } if ($this->dateCreatedAfter) { $where[] = qsprintf( $conn, 'm.dateCreated >= %d', $this->dateCreatedAfter); } if ($this->dateCreatedBefore) { $where[] = qsprintf( $conn, 'm.dateCreated <= %d', $this->dateCreatedBefore); } + if ($this->flagColor != '-1' && $this->flagColor !== null) { + $flags = id(new PhabricatorFlagQuery()) + ->withTypes(array(PhabricatorMacroPHIDTypeMacro::TYPECONST)) + ->withColor($this->flagColor) + ->setViewer($this->getViewer()) + ->execute(); + + if (empty($flags)) { + throw new PhabricatorEmptyQueryException('No matching flags.'); + } else { + $where[] = qsprintf( + $conn, + 'm.phid IN (%Ls)', + mpull($flags, 'getObjectPHID')); + } + } + $where[] = $this->buildPagingClause($conn); return $this->formatWhereClause($where); } protected function willFilterPage(array $macros) { $file_phids = mpull($macros, 'getFilePHID'); $files = id(new PhabricatorFileQuery()) ->setViewer($this->getViewer()) ->withPHIDs($file_phids) ->execute(); $files = mpull($files, null, 'getPHID'); foreach ($macros as $key => $macro) { $file = idx($files, $macro->getFilePHID()); if (!$file) { unset($macros[$key]); continue; } $macro->attachFile($file); } return $macros; } protected function getPagingColumn() { return 'm.id'; } } diff --git a/src/applications/macro/query/PhabricatorMacroSearchEngine.php b/src/applications/macro/query/PhabricatorMacroSearchEngine.php index a60fdbed9a..989dbe5fb6 100644 --- a/src/applications/macro/query/PhabricatorMacroSearchEngine.php +++ b/src/applications/macro/query/PhabricatorMacroSearchEngine.php @@ -1,143 +1,156 @@ setParameter( 'authorPHIDs', array_values($request->getArr('authors'))); $saved->setParameter('status', $request->getStr('status')); $saved->setParameter('names', $request->getStrList('names')); $saved->setParameter('nameLike', $request->getStr('nameLike')); $saved->setParameter('createdStart', $request->getStr('createdStart')); $saved->setParameter('createdEnd', $request->getStr('createdEnd')); + $saved->setParameter('flagColor', $request->getStr('flagColor')); return $saved; } public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhabricatorMacroQuery()) ->withIDs($saved->getParameter('ids', array())) ->withPHIDs($saved->getParameter('phids', array())) ->withAuthorPHIDs($saved->getParameter('authorPHIDs', array())); $status = $saved->getParameter('status'); $options = PhabricatorMacroQuery::getStatusOptions(); if (empty($options[$status])) { $status = head_key($options); } $query->withStatus($status); $names = $saved->getParameter('names', array()); if ($names) { $query->withNames($names); } $like = $saved->getParameter('nameLike'); if (strlen($like)) { $query->withNameLike($like); } $start = $this->parseDateTime($saved->getParameter('createdStart')); $end = $this->parseDateTime($saved->getParameter('createdEnd')); if ($start) { $query->withDateCreatedAfter($start); } if ($end) { $query->withDateCreatedBefore($end); } + $color = $saved->getParameter('flagColor'); + if (strlen($color)) { + $query->withFlagColor($color); + } + return $query; } public function buildSearchForm( AphrontFormView $form, PhabricatorSavedQuery $saved_query) { $phids = $saved_query->getParameter('authorPHIDs', array()); $handles = id(new PhabricatorObjectHandleData($phids)) ->setViewer($this->requireViewer()) ->loadHandles(); $author_tokens = mpull($handles, 'getFullName', 'getPHID'); $status = $saved_query->getParameter('status'); $names = implode(', ', $saved_query->getParameter('names', array())); $like = $saved_query->getParameter('nameLike'); + $color = $saved_query->getParameter('flagColor', "-1"); $form ->appendChild( id(new AphrontFormSelectControl()) ->setName('status') ->setLabel(pht('Status')) ->setOptions(PhabricatorMacroQuery::getStatusOptions()) ->setValue($status)) ->appendChild( id(new AphrontFormTokenizerControl()) ->setDatasource('/typeahead/common/users/') ->setName('authors') ->setLabel(pht('Authors')) ->setValue($author_tokens)) ->appendChild( id(new AphrontFormTextControl()) ->setName('nameLike') ->setLabel(pht('Name Contains')) ->setValue($like)) ->appendChild( id(new AphrontFormTextControl()) ->setName('names') ->setLabel(pht('Exact Names')) - ->setValue($names)); + ->setValue($names)) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setName('flagColor') + ->setLabel(pht('Marked with Flag')) + ->setOptions(PhabricatorMacroQuery::getFlagColorsOptions()) + ->setValue($color)); $this->buildDateRange( $form, $saved_query, 'createdStart', pht('Created After'), 'createdEnd', pht('Created Before')); } protected function getURI($path) { return '/macro/'.$path; } public function getBuiltinQueryNames() { $names = array( 'active' => pht('Active'), 'all' => pht('All'), ); if ($this->requireViewer()->isLoggedIn()) { $names['authored'] = pht('Authored'); } return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); switch ($query_key) { case 'active': return $query; case 'all': return $query->setParameter( 'status', PhabricatorMacroQuery::STATUS_ANY); case 'authored': return $query->setParameter( 'authorPHIDs', array($this->requireViewer()->getPHID())); } return parent::buildSavedQueryFromBuiltin($query_key); } }