diff --git a/src/applications/phriction/controller/PhrictionListController.php b/src/applications/phriction/controller/PhrictionListController.php index d1e91ef6bf..5768b07e6f 100644 --- a/src/applications/phriction/controller/PhrictionListController.php +++ b/src/applications/phriction/controller/PhrictionListController.php @@ -1,180 +1,220 @@ view = idx($data, 'view'); } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $views = array( 'active' => pht('Active Documents'), 'all' => pht('All Documents'), 'updates' => pht('Recently Updated'), ); if (empty($views[$this->view])) { $this->view = 'active'; } $nav = $this->buildSideNavView($this->view); $header = id(new PhabricatorHeaderView()) ->setHeader($views[$this->view]); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addCrumb(id(new PhabricatorCrumbView()) ->setName($views[$this->view]) ->setHref($this->getApplicationURI('list/' . $this->view))); $nav->appendChild( array( $crumbs, $header, )); $pager = id(new AphrontCursorPagerView()) ->readFromRequest($request); $query = id(new PhrictionDocumentQuery()) ->setViewer($user); switch ($this->view) { case 'active': $query->withStatus(PhrictionDocumentQuery::STATUS_OPEN); break; case 'all': $query->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB); break; case 'updates': $query->withStatus(PhrictionDocumentQuery::STATUS_NONSTUB); $query->setOrder(PhrictionDocumentQuery::ORDER_UPDATED); break; default: throw new Exception("Unknown view '{$this->view}'!"); } - $documents = $query->executeWithCursorPager($pager); + $this->documents = $query->executeWithCursorPager($pager); + + $changeref_docs = array(); + if ($this->view == 'updates') { + // Loading some documents here since they may not appear in the query + // results. + $changeref_ids = array_filter(mpull( + mpull($this->documents, 'getContent'), 'getChangeRef')); + if ($changeref_ids) { + $changeref_docs = id(new PhrictionDocumentQuery()) + ->setViewer($user) + ->withIDs($changeref_ids) + ->execute(); + } + } $phids = array(); - foreach ($documents as $document) { + foreach ($this->documents as $document) { $phids[] = $document->getContent()->getAuthorPHID(); if ($document->hasProject()) { $phids[] = $document->getProject()->getPHID(); } } - $handles = $this->loadViewerHandles($phids); - - $rows = array(); - foreach ($documents as $document) { - $project_link = 'None'; - if ($document->hasProject()) { - $project_phid = $document->getProject()->getPHID(); - $project_link = $handles[$project_phid]->renderLink(); - } + $this->handles = $this->loadViewerHandles($phids); - $content = $document->getContent(); + $list = new PhabricatorObjectItemListView(); - $change_type = null; + foreach ($this->documents as $document) { if ($this->view == 'updates') { - $change_type = $content->getChangeType(); - switch ($content->getChangeType()) { - case PhrictionChangeType::CHANGE_DELETE: - case PhrictionChangeType::CHANGE_EDIT: - $change_type = PhrictionChangeType::getChangeTypeLabel( - $change_type); - break; - case PhrictionChangeType::CHANGE_MOVE_HERE: - case PhrictionChangeType::CHANGE_MOVE_AWAY: - $change_ref = $content->getChangeRef(); - $ref_doc = $documents[$change_ref]; - $ref_doc_slug = PhrictionDocument::getSlugURI( - $ref_doc->getSlug()); - $ref_doc_link = hsprintf('
%s', $ref_doc_slug, - phutil_utf8_shorten($ref_doc_slug, 15)); - - if ($change_type == PhrictionChangeType::CHANGE_MOVE_HERE) { - $change_type = pht('Moved from %s', $ref_doc_link); - } else { - $change_type = pht('Moved to %s', $ref_doc_link); - } - break; - default: - throw new Exception("Unknown change type!"); - break; - } + $list->addItem( + $this->buildItemForUpdates($document, $changeref_docs)); + } else { + $list->addItem( + $this->buildItemTheCasualWay($document)); } - - $rows[] = array( - $handles[$content->getAuthorPHID()]->renderLink(), - $change_type, - phutil_tag( - 'a', - array( - 'href' => PhrictionDocument::getSlugURI($document->getSlug()), - ), - $content->getTitle()), - $project_link, - phabricator_date($content->getDateCreated(), $user), - phabricator_time($content->getDateCreated(), $user), - ); } - $document_table = new AphrontTableView($rows); - $document_table->setHeaders( - array( - pht('Last Editor'), - pht('Change Type'), - pht('Title'), - pht('Project'), - pht('Last Update'), - pht('Time'), - )); + $nav->appendChild($list); + $nav->appendChild($pager); - $document_table->setColumnClasses( + return $this->buildApplicationPage( + $nav, array( - '', - '', - 'wide pri', - '', - 'right', - 'right', + 'title' => pht('Document Index'), + 'dust' => true, )); + } - $document_table->setColumnVisibility( - array( - true, - $this->view == 'updates', - true, - true, - true, - true, - )); + private function buildItemTheCasualWay(PhrictionDocument $document) { + $user = $this->getRequest()->getUser(); - $panel = new AphrontPanelView(); - $panel->setNoBackground(); - $panel->appendChild($document_table); - $panel->appendChild($pager); + $project_link = null; + if ($document->hasProject()) { + $project_phid = $document->getProject()->getPHID(); + $project_link = $this->handles[$project_phid]->renderLink(); + } - $nav->appendChild($panel); + $content = $document->getContent(); + $author = $this->handles[$content->getAuthorPHID()]->renderLink(); + $title = $content->getTitle(); + + $slug = $document->getSlug(); + $slug_uri = PhrictionDocument::getSlugURI($slug); + $edit_uri = '/phriction/edit/' . $document->getID() . '/'; + $history_uri = PhrictionDocument::getSlugURI($slug, 'history'); + + $item = id(new PhabricatorObjectItemView()) + ->setHeader($title) + ->setHref($slug_uri) + ->addAttribute(pht('By %s', $author)) + ->addAttribute(pht('Updated: %s', + phabricator_datetime($content->getDateCreated(), $user))) + ->addAttribute($slug_uri); + + if ($project_link) { + $item->addAttribute(pht('Project %s', $project_link)); + } - return $this->buildApplicationPage( - $nav, - array( - 'title' => pht('Phriction Main'), - 'dust' => true, - )); + return $item; + } + + private function buildItemForUpdates(PhrictionDocument $document, + array $docs_from_refs) { + + $user = $this->getRequest()->getUser(); + + $content = $document->getContent(); + $version = $content->getVersion(); + $author = $this->handles[$content->getAuthorPHID()]->renderLink(); + $title = $content->getTitle(); + + $slug = $document->getSlug(); + $slug_uri = PhrictionDocument::getSlugURI($slug); + $document_link = hsprintf('%s', $slug_uri, $title); + + $change_type = $content->getChangeType(); + switch ($content->getChangeType()) { + case PhrictionChangeType::CHANGE_DELETE: + $change_type = pht('%s deleted %s', $author, $document_link); + $color = 'red'; + break; + case PhrictionChangeType::CHANGE_EDIT: + $change_type = pht('%s edited %s', $author, $document_link); + $color = 'blue'; + break; + case PhrictionChangeType::CHANGE_MOVE_HERE: + case PhrictionChangeType::CHANGE_MOVE_AWAY: + $change_ref = $content->getChangeRef(); + $ref_doc = $docs_from_refs[$change_ref]; + $ref_doc_slug = PhrictionDocument::getSlugURI( + $ref_doc->getSlug()); + $ref_doc_link = hsprintf('%1$s', $ref_doc_slug); + + if ($change_type == PhrictionChangeType::CHANGE_MOVE_HERE) { + $change_type = pht('%s moved %s from %s', $author, $document_link, + $ref_doc_link); + $color = 'yellow'; + } else { + $change_type = pht('%s moved %s to %s', $author, $document_link, + $ref_doc_link); + $color = 'orange'; + } + break; + default: + throw new Exception("Unknown change type!"); + break; + } + + $item = id(new PhabricatorObjectItemView()) + ->setHeader($change_type) + ->setBarColor($color) + ->addAttribute(phabricator_datetime($content->getDateCreated(), $user)) + ->addAttribute($slug_uri); + + if ($content->getDescription()) { + $item->addAttribute($content->getDescription()); + } + + if ($version > 1) { + $diff_uri = new PhutilURI('/phriction/diff/'.$document->getID().'/'); + $uri = $diff_uri->alter('l', $version - 1)->alter('r', $version); + $item->addIcon('history', pht('View Change'), $uri); + } else { + $item->addIcon('history', pht('No diff available')); + } + + return $item; } } diff --git a/src/applications/phriction/query/PhrictionDocumentQuery.php b/src/applications/phriction/query/PhrictionDocumentQuery.php index d918b3b84f..3cdd0e2abf 100644 --- a/src/applications/phriction/query/PhrictionDocumentQuery.php +++ b/src/applications/phriction/query/PhrictionDocumentQuery.php @@ -1,174 +1,175 @@ ids = $ids; return $this; } public function withPHIDs(array $phids) { $this->phids = $phids; return $this; } public function withStatus($status) { $this->status = $status; return $this; } public function setOrder($order) { $this->order = $order; return $this; } protected function loadPage() { $document = new PhrictionDocument(); $conn_r = $document->establishConnection('r'); $rows = queryfx_all( $conn_r, 'SELECT * FROM %T %Q %Q %Q', $document->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r)); return $document->loadAllFromArray($rows); } protected function willFilterPage(array $documents) { if (!$documents) { return array(); } $contents = id(new PhrictionContent())->loadAllWhere( 'id IN (%Ld)', mpull($documents, 'getContentID')); foreach ($documents as $key => $document) { $content_id = $document->getContentID(); if (empty($contents[$content_id])) { unset($documents[$key]); continue; } $document->attachContent($contents[$content_id]); } $project_slugs = array(); foreach ($documents as $key => $document) { $slug = $document->getSlug(); if (!PhrictionDocument::isProjectSlug($slug)) { continue; } $project_slugs[$key] = PhrictionDocument::getProjectSlugIdentifier($slug); } if ($project_slugs) { $projects = id(new PhabricatorProjectQuery()) ->setViewer($this->getViewer()) ->withPhrictionSlugs($project_slugs) ->execute(); $projects = mpull($projects, null, 'getPhrictionSlug'); foreach ($documents as $key => $document) { $slug = idx($project_slugs, $key); if ($slug) { $project = idx($projects, $slug); if (!$project) { unset($documents[$key]); continue; } $document->attachProject($project); } } } return $documents; } protected function buildWhereClause(AphrontDatabaseConnection $conn) { $where = array(); if ($this->ids) { $where[] = qsprintf( $conn, 'id IN (%Ld)', $this->ids); } if ($this->phids) { $where[] = qsprintf( $conn, 'id IN (%Ld)', $this->phids); } switch ($this->status) { case self::STATUS_OPEN: $where[] = qsprintf( $conn, 'status NOT IN (%Ld)', array( PhrictionDocumentStatus::STATUS_DELETED, PhrictionDocumentStatus::STATUS_MOVED, PhrictionDocumentStatus::STATUS_STUB, )); break; case self::STATUS_NONSTUB: $where[] = qsprintf( $conn, 'status NOT IN (%Ld)', array( + PhrictionDocumentStatus::STATUS_MOVED, PhrictionDocumentStatus::STATUS_STUB, )); break; case self::STATUS_ANY: break; default: throw new Exception("Unknown status '{$this->status}'!"); } $where[] = $this->buildPagingClause($conn); return $this->formatWhereClause($where); } protected function getPagingColumn() { switch ($this->order) { case self::ORDER_CREATED: return 'id'; case self::ORDER_UPDATED: return 'contentID'; default: throw new Exception("Unknown order '{$this->order}'!"); } } protected function getPagingValue($result) { switch ($this->order) { case self::ORDER_CREATED: return $result->getID(); case self::ORDER_UPDATED: return $result->getContentID(); default: throw new Exception("Unknown order '{$this->order}'!"); } } }