From 86783fcd07a2dbda3aa619c0ba1b47c89b7b2a6c Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 15 Jul 2011 14:56:39 -0700 Subject: [PATCH] Show child documents on Phriction pages Summary: Pull the next couple levels of hierarchy and render them at the bottom of the page. This might need some tweaking but it seems OK at first glance. Test Plan: https://secure.phabricator.com/file/info/PHID-FILE-ef0af5d4dc6dceaeb2e3/ Also reduced limit to 1 and verified the "more" behavior worked properly. Reviewed By: hsb Reviewers: hsb, codeblock, jungejason, tuomaspelkonen, aran CC: aran, hsb Differential Revision: 676 --- .../document/PhrictionDocumentController.php | 125 +++++++++++++++++- .../controller/document/__init__.php | 1 + .../phriction/phriction-document-css.css | 18 +++ 3 files changed, 143 insertions(+), 1 deletion(-) diff --git a/src/applications/phriction/controller/document/PhrictionDocumentController.php b/src/applications/phriction/controller/document/PhrictionDocumentController.php index 69ddea339d..458c4f3e57 100644 --- a/src/applications/phriction/controller/document/PhrictionDocumentController.php +++ b/src/applications/phriction/controller/document/PhrictionDocumentController.php @@ -137,6 +137,8 @@ class PhrictionDocumentController $version_note = $version_note->render(); } + $children = $this->renderChildren($slug); + $page = '
'. $button. @@ -144,7 +146,8 @@ class PhrictionDocumentController $breadcrumbs. '
'. $version_note. - $page_content; + $page_content. + $children; return $this->buildStandardPageResponse( $page, @@ -208,4 +211,124 @@ class PhrictionDocumentController ''; } + private function renderChildren($slug) { + $document_dao = new PhrictionDocument(); + $content_dao = new PhrictionContent(); + $conn = $document_dao->establishConnection('r'); + + $limit = 50; + $d_child = PhrictionDocument::getSlugDepth($slug) + 1; + $d_grandchild = PhrictionDocument::getSlugDepth($slug) + 2; + + // Select children and grandchildren. + $children = queryfx_all( + $conn, + 'SELECT d.slug, d.depth, c.title FROM %T d JOIN %T c + ON d.contentID = c.id + WHERE d.slug LIKE %> AND d.depth IN (%d, %d) + ORDER BY d.depth, c.title LIMIT %d', + $document_dao->getTableName(), + $content_dao->getTableName(), + ($slug == '/' ? '' : $slug), + $d_child, + $d_grandchild, + $limit); + + if (!$children) { + return; + } + + // We're going to render in one of three modes to try to accommodate + // different information scales: + // + // - If we found fewer than $limit rows, we know we have all the children + // and grandchildren and there aren't all that many. We can just render + // everything. + // - If we found $limit rows but the results included some grandchildren, + // we just throw them out and render only the children, as we know we + // have them all. + // - If we found $limit rows and the results have no grandchildren, we + // have a ton of children. Render them and then let the user know that + // this is not an exhaustive list. + + if (count($children) == $limit) { + $more_children = true; + foreach ($children as $child) { + if ($child['depth'] == $d_grandchild) { + $more_children = false; + } + } + $show_grandchildren = false; + } else { + $show_grandchildren = true; + $more_children = false; + } + + $grandchildren = array(); + foreach ($children as $key => $child) { + if ($child['depth'] == $d_child) { + continue; + } else { + unset($children[$key]); + if ($show_grandchildren) { + $ancestors = PhrictionDocument::getSlugAncestry($child['slug']); + $grandchildren[end($ancestors)][] = $child; + } + } + } + + // Fill in any missing children. + $known_slugs = ipull($children, null, 'slug'); + foreach ($grandchildren as $slug => $ignored) { + if (empty($known_slugs[$slug])) { + $children[] = array( + 'slug' => $slug, + 'depth' => $d_child, + 'title' => PhrictionDocument::getDefaultSlugTitle($slug), + 'empty' => true, + ); + } + } + + $list = array(); + $list[] = ''; + $list = implode("\n", $list); + + return + '
'. + '
Document Hierarchy
'. + $list. + '
'; + } + + private function renderChildDocumentLink(array $info) { + $item = phutil_render_tag( + 'a', + array( + 'href' => PhrictionDocument::getSlugURI($info['slug']), + ), + phutil_escape_html($info['title'])); + + if (isset($info['empty'])) { + $item = ''.$item.''; + } + + return '
  • '.$item.'
  • '; + } + } diff --git a/src/applications/phriction/controller/document/__init__.php b/src/applications/phriction/controller/document/__init__.php index 79db304aa6..0cc26961ce 100644 --- a/src/applications/phriction/controller/document/__init__.php +++ b/src/applications/phriction/controller/document/__init__.php @@ -15,6 +15,7 @@ phutil_require_module('phabricator', 'applications/phriction/controller/base'); phutil_require_module('phabricator', 'applications/phriction/storage/content'); phutil_require_module('phabricator', 'applications/phriction/storage/document'); phutil_require_module('phabricator', 'infrastructure/celerity/api'); +phutil_require_module('phabricator', 'storage/queryfx'); phutil_require_module('phabricator', 'view/form/error'); phutil_require_module('phabricator', 'view/utils'); diff --git a/webroot/rsrc/css/application/phriction/phriction-document-css.css b/webroot/rsrc/css/application/phriction/phriction-document-css.css index 508acf9ff8..f69c3a9ac0 100644 --- a/webroot/rsrc/css/application/phriction/phriction-document-css.css +++ b/webroot/rsrc/css/application/phriction/phriction-document-css.css @@ -38,3 +38,21 @@ .phriction-document-crumbs a { font-weight: bold; } + +.phriction-children { + padding: 1em 2em; + background: #eeeeee; + border-top: 1px solid #dddddd; +} + +.phriction-children ul { + margin-left: 2.5em; + list-style: circle; + color: #999999; +} + +.phriction-children-header { + padding: 0 0 .5em 0; + margin: 0; + font-weight: bold; +}