diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -9359,8 +9359,9 @@ 'PhabricatorFlaggableInterface', 'PhabricatorTokenReceiverInterface', 'PhabricatorDestructibleInterface', - 'PhabricatorApplicationTransactionInterface', 'PhabricatorFulltextInterface', + 'PhabricatorProjectInterface', + 'PhabricatorApplicationTransactionInterface', ), 'PhrictionDocumentAuthorHeraldField' => 'PhrictionDocumentHeraldField', 'PhrictionDocumentContentHeraldField' => 'PhrictionDocumentHeraldField', diff --git a/src/applications/phriction/controller/PhrictionEditController.php b/src/applications/phriction/controller/PhrictionEditController.php --- a/src/applications/phriction/controller/PhrictionEditController.php +++ b/src/applications/phriction/controller/PhrictionEditController.php @@ -9,6 +9,7 @@ $current_version = null; if ($id) { + $is_new = false; $document = id(new PhrictionDocumentQuery()) ->setViewer($viewer) ->withIDs(array($id)) @@ -54,9 +55,11 @@ if ($document) { $content = $document->getContent(); $current_version = $content->getVersion(); + $is_new = false; } else { $document = PhrictionDocument::initializeNewDocument($viewer, $slug); $content = $document->getContent(); + $is_new = true; } } @@ -91,11 +94,7 @@ $draft_note->setSeverity(PHUIInfoView::SEVERITY_NOTICE); $draft_note->setTitle(pht('Recovered Draft')); $draft_note->appendChild( - hsprintf( - '

%s

', - pht( - 'Showing a saved draft of your edits, you can %s.', - $discard))); + pht('Showing a saved draft of your edits, you can %s.', $discard)); } else { $content_text = $content->getContent(); $draft_note = null; @@ -112,6 +111,15 @@ $v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID( $document->getPHID()); + if ($is_new) { + $v_projects = array(); + } else { + $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs( + $document->getPHID(), + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); + $v_projects = array_reverse($v_projects); + } + if ($request->isFormPost()) { $title = $request->getStr('title'); @@ -120,7 +128,8 @@ $current_version = $request->getInt('contentVersion'); $v_view = $request->getStr('viewPolicy'); $v_edit = $request->getStr('editPolicy'); - $v_cc = $request->getArr('cc'); + $v_cc = $request->getArr('cc'); + $v_projects = $request->getArr('projects'); $xactions = array(); $xactions[] = id(new PhrictionTransaction()) @@ -139,6 +148,12 @@ ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS) ->setNewValue(array('=' => $v_cc)); + $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; + $xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) + ->setMetadataValue('edge:type', $proj_edge_type) + ->setNewValue(array('=' => array_fuse($v_projects))); + $editor = id(new PhrictionTransactionEditor()) ->setActor($viewer) ->setContentSourceFromRequest($request) @@ -232,6 +247,12 @@ ->setUser($viewer)) ->appendControl( id(new AphrontFormTokenizerControl()) + ->setLabel(pht('Projects')) + ->setName('projects') + ->setValue($v_projects) + ->setDatasource(new PhabricatorProjectDatasource())) + ->appendControl( + id(new AphrontFormTokenizerControl()) ->setLabel(pht('Subscribers')) ->setName('cc') ->setValue($v_cc) diff --git a/src/applications/phriction/editor/PhrictionTransactionEditor.php b/src/applications/phriction/editor/PhrictionTransactionEditor.php --- a/src/applications/phriction/editor/PhrictionTransactionEditor.php +++ b/src/applications/phriction/editor/PhrictionTransactionEditor.php @@ -80,13 +80,14 @@ public function getTransactionTypes() { $types = parent::getTransactionTypes(); - $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhrictionTransaction::TYPE_TITLE; $types[] = PhrictionTransaction::TYPE_CONTENT; $types[] = PhrictionTransaction::TYPE_DELETE; $types[] = PhrictionTransaction::TYPE_MOVE_TO; $types[] = PhrictionTransaction::TYPE_MOVE_AWAY; + $types[] = PhabricatorTransactions::TYPE_EDGE; + $types[] = PhabricatorTransactions::TYPE_COMMENT; $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; diff --git a/src/applications/phriction/query/PhrictionDocumentQuery.php b/src/applications/phriction/query/PhrictionDocumentQuery.php --- a/src/applications/phriction/query/PhrictionDocumentQuery.php +++ b/src/applications/phriction/query/PhrictionDocumentQuery.php @@ -17,8 +17,6 @@ const STATUS_OPEN = 'status-open'; const STATUS_NONSTUB = 'status-nonstub'; - const ORDER_CREATED = 'order-created'; - const ORDER_UPDATED = 'order-updated'; const ORDER_HIERARCHY = 'order-hierarchy'; public function withIDs(array $ids) { @@ -61,38 +59,15 @@ return $this; } - public function setOrder($order) { - switch ($order) { - case self::ORDER_CREATED: - $this->setOrderVector(array('id')); - break; - case self::ORDER_UPDATED: - $this->setOrderVector(array('updated')); - break; - case self::ORDER_HIERARCHY: - $this->setOrderVector(array('depth', 'title', 'updated')); - break; - default: - throw new Exception(pht('Unknown order "%s".', $order)); - } - - return $this; - } - protected function loadPage() { - $table = new PhrictionDocument(); - $conn_r = $table->establishConnection('r'); + return $this->loadStandardPage($this->newResultObject()); + } - $rows = queryfx_all( - $conn_r, - 'SELECT d.* FROM %T d %Q %Q %Q %Q', - $table->getTableName(), - $this->buildJoinClause($conn_r), - $this->buildWhereClause($conn_r), - $this->buildOrderClause($conn_r), - $this->buildLimitClause($conn_r)); + public function newResultObject() { + return new PhrictionDocument(); + } - $documents = $table->loadAllFromArray($rows); + protected function willFilterPage(array $documents) { if ($documents) { $ancestor_slugs = array(); @@ -104,6 +79,8 @@ } if ($ancestor_slugs) { + $table = new PhrictionDocument(); + $conn_r = $table->establishConnection('r'); $ancestors = queryfx_all( $conn_r, 'SELECT * FROM %T WHERE slug IN (%Ls)', @@ -122,11 +99,6 @@ } } } - - return $documents; - } - - protected function willFilterPage(array $documents) { // To view a Phriction document, you must also be able to view all of the // ancestor documents. Filter out documents which have ancestors that are // not visible. @@ -190,58 +162,59 @@ return $documents; } - protected function buildJoinClause(AphrontDatabaseConnection $conn) { - $join = ''; + protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { + $joins = array(); if ($this->getOrderVector()->containsKey('updated')) { $content_dao = new PhrictionContent(); - $join = qsprintf( + $joins[] = qsprintf( $conn, 'JOIN %T c ON d.contentID = c.id', $content_dao->getTableName()); } - return $join; + return $joins; } - protected function buildWhereClause(AphrontDatabaseConnection $conn) { - $where = array(); - if ($this->ids) { + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { + $where = parent::buildWhereClauseParts($conn); + + if ($this->ids !== null) { $where[] = qsprintf( $conn, 'd.id IN (%Ld)', $this->ids); } - if ($this->phids) { + if ($this->phids !== null) { $where[] = qsprintf( $conn, 'd.phid IN (%Ls)', $this->phids); } - if ($this->slugs) { + if ($this->slugs !== null) { $where[] = qsprintf( $conn, 'd.slug IN (%Ls)', $this->slugs); } - if ($this->statuses) { + if ($this->statuses !== null) { $where[] = qsprintf( $conn, 'd.status IN (%Ld)', $this->statuses); } - if ($this->slugPrefix) { + if ($this->slugPrefix !== null) { $where[] = qsprintf( $conn, 'd.slug LIKE %>', $this->slugPrefix); } - if ($this->depths) { + if ($this->depths !== null) { $where[] = qsprintf( $conn, 'd.depth IN (%Ld)', @@ -274,9 +247,16 @@ throw new Exception(pht("Unknown status '%s'!", $this->status)); } - $where[] = $this->buildPagingClause($conn); + return $where; + } - return $this->formatWhereClause($where); + public function getBuiltinOrders() { + return array( + self::ORDER_HIERARCHY => array( + 'vector' => array('depth', 'title', 'updated'), + 'name' => pht('Hierarchy'), + ), + ) + parent::getBuiltinOrders(); } public function getOrderableColumns() { @@ -331,6 +311,9 @@ } } + protected function getPrimaryTableAlias() { + return 'd'; + } public function getQueryApplicationClass() { return 'PhabricatorPhrictionApplication'; diff --git a/src/applications/phriction/query/PhrictionSearchEngine.php b/src/applications/phriction/query/PhrictionSearchEngine.php --- a/src/applications/phriction/query/PhrictionSearchEngine.php +++ b/src/applications/phriction/query/PhrictionSearchEngine.php @@ -11,52 +11,29 @@ return 'PhabricatorPhrictionApplication'; } - public function buildSavedQueryFromRequest(AphrontRequest $request) { - $saved = new PhabricatorSavedQuery(); - - $saved->setParameter('status', $request->getStr('status')); - $saved->setParameter('order', $request->getStr('order')); - - return $saved; - } - - public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { - $query = id(new PhrictionDocumentQuery()) + public function newQuery() { + return id(new PhrictionDocumentQuery()) ->needContent(true) ->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB); + } - $status = $saved->getParameter('status'); - $status = idx($this->getStatusValues(), $status); - if ($status) { - $query->withStatus($status); - } + protected function buildQueryFromParameters(array $map) { + $query = $this->newQuery(); - $order = $saved->getParameter('order'); - $order = idx($this->getOrderValues(), $order); - if ($order) { - $query->setOrder($order); + if ($map['status']) { + $query->withStatus($map['status']); } return $query; } - public function buildSearchForm( - AphrontFormView $form, - PhabricatorSavedQuery $saved_query) { - - $form - ->appendChild( - id(new AphrontFormSelectControl()) - ->setLabel(pht('Status')) - ->setName('status') - ->setOptions($this->getStatusOptions()) - ->setValue($saved_query->getParameter('status'))) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setLabel(pht('Order')) - ->setName('order') - ->setOptions($this->getOrderOptions()) - ->setValue($saved_query->getParameter('order'))); + protected function buildCustomSearchFields() { + return array( + id(new PhabricatorSearchSelectField()) + ->setKey('status') + ->setLabel(pht('Status')) + ->setOptions($this->getStatusOptions()), + ); } protected function getURI($path) { @@ -66,7 +43,6 @@ protected function getBuiltinQueryNames() { $names = array( 'active' => pht('Active'), - 'updated' => pht('Updated'), 'all' => pht('All'), ); @@ -79,12 +55,11 @@ $query->setQueryKey($query_key); switch ($query_key) { - case 'active': - return $query->setParameter('status', 'active'); case 'all': return $query; - case 'updated': - return $query->setParameter('order', 'updated'); + case 'active': + return $query->setParameter( + 'status', PhrictionDocumentQuery::STATUS_OPEN); } return parent::buildSavedQueryFromBuiltin($query_key); @@ -92,29 +67,8 @@ private function getStatusOptions() { return array( - 'active' => pht('Show Active Documents'), - 'all' => pht('Show All Documents'), - ); - } - - private function getStatusValues() { - return array( - 'active' => PhrictionDocumentQuery::STATUS_OPEN, - 'all' => PhrictionDocumentQuery::STATUS_NONSTUB, - ); - } - - private function getOrderOptions() { - return array( - 'created' => pht('Date Created'), - 'updated' => pht('Date Updated'), - ); - } - - private function getOrderValues() { - return array( - 'created' => PhrictionDocumentQuery::ORDER_CREATED, - 'updated' => PhrictionDocumentQuery::ORDER_UPDATED, + PhrictionDocumentQuery::STATUS_OPEN => pht('Show Active Documents'), + PhrictionDocumentQuery::STATUS_NONSTUB => pht('Show All Documents'), ); } diff --git a/src/applications/phriction/storage/PhrictionDocument.php b/src/applications/phriction/storage/PhrictionDocument.php --- a/src/applications/phriction/storage/PhrictionDocument.php +++ b/src/applications/phriction/storage/PhrictionDocument.php @@ -7,8 +7,9 @@ PhabricatorFlaggableInterface, PhabricatorTokenReceiverInterface, PhabricatorDestructibleInterface, - PhabricatorApplicationTransactionInterface, - PhabricatorFulltextInterface { + PhabricatorFulltextInterface, + PhabricatorProjectInterface, + PhabricatorApplicationTransactionInterface { protected $slug; protected $depth;