Page MenuHomestyx hydra

No OneTemporary

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
@@ -1,211 +1,334 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhrictionDocumentController
extends PhrictionController {
private $slug;
public function willProcessRequest(array $data) {
$this->slug = $data['slug'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$slug = PhrictionDocument::normalizeSlug($this->slug);
if ($slug != $this->slug) {
$uri = PhrictionDocument::getSlugURI($slug);
// Canonicalize pages to their one true URI.
return id(new AphrontRedirectResponse())->setURI($uri);
}
require_celerity_resource('phriction-document-css');
$document = id(new PhrictionDocument())->loadOneWhere(
'slug = %s',
$slug);
$breadcrumbs = $this->renderBreadcrumbs($slug);
$version_note = null;
if (!$document) {
$create_uri = '/phriction/edit/?slug='.$slug;
$page_content =
'<div class="phriction-content">'.
'<em>No content here!</em><br />'.
'No document found at <tt>'.phutil_escape_html($slug).'</tt>. '.
'You can <strong>'.
phutil_render_tag(
'a',
array(
'href' => $create_uri,
),
'create a new document').'</strong>.'.
'</div>';
$page_title = 'Page Not Found';
$button = phutil_render_tag(
'a',
array(
'href' => $create_uri,
'class' => 'green button',
),
'Create Page');
} else {
$version = $request->getInt('v');
if ($version) {
$content = id(new PhrictionContent())->loadOneWhere(
'documentID = %d AND version = %d',
$document->getID(),
$version);
if (!$content) {
return new Aphront404Response();
}
if ($content->getID() != $document->getContentID()) {
$version_note = new AphrontErrorView();
$version_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$version_note->setTitle('Older Version');
$version_note->appendChild(
'You are viewing an older version of this document, as it '.
'appeared on '.
phabricator_datetime($content->getDateCreated(), $user).'.');
}
} else {
$content = id(new PhrictionContent())->load($document->getContentID());
}
$page_title = $content->getTitle();
$phids = array($content->getAuthorPHID());
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
$age = time() - $content->getDateCreated();
$age = floor($age / (60 * 60 * 24));
if ($age < 1) {
$when = 'today';
} else if ($age == 1) {
$when = 'yesterday';
} else {
$when = "{$age} days ago";
}
$byline =
'<div class="phriction-byline">'.
"Last updated {$when} by ".
$handles[$content->getAuthorPHID()]->renderLink().'.'.
'</div>';
$engine = PhabricatorMarkupEngine::newPhrictionMarkupEngine();
$page_content =
'<div class="phriction-content">'.
$byline.
'<div class="phabricator-remarkup">'.
$engine->markupText($content->getContent()).
'</div>'.
'</div>';
$button = phutil_render_tag(
'a',
array(
'href' => '/phriction/edit/'.$document->getID().'/',
'class' => 'button',
),
'Edit Page');
}
if ($version_note) {
$version_note = $version_note->render();
}
+ $children = $this->renderChildren($slug);
+
$page =
'<div class="phriction-header">'.
$button.
'<h1>'.phutil_escape_html($page_title).'</h1>'.
$breadcrumbs.
'</div>'.
$version_note.
- $page_content;
+ $page_content.
+ $children;
return $this->buildStandardPageResponse(
$page,
array(
'title' => 'Phriction - '.$page_title,
'history' => PhrictionDocument::getSlugURI($slug, 'history'),
));
}
private function renderBreadcrumbs($slug) {
$ancestor_handles = array();
$ancestral_slugs = PhrictionDocument::getSlugAncestry($slug);
$ancestral_slugs[] = $slug;
if ($ancestral_slugs) {
$empty_slugs = array_fill_keys($ancestral_slugs, null);
$ancestors = id(new PhrictionDocument())->loadAllWhere(
'slug IN (%Ls)',
$ancestral_slugs);
$ancestors = mpull($ancestors, null, 'getSlug');
$ancestor_phids = mpull($ancestors, 'getPHID');
$handles = array();
if ($ancestor_phids) {
$handles = id(new PhabricatorObjectHandleData($ancestor_phids))
->loadHandles();
}
$ancestor_handles = array();
foreach ($ancestral_slugs as $slug) {
if (isset($ancestors[$slug])) {
$ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()];
} else {
$handle = new PhabricatorObjectHandle();
$handle->setName(PhrictionDocument::getDefaultSlugTitle($slug));
$handle->setURI(PhrictionDocument::getSlugURI($slug));
$ancestor_handles[] = $handle;
}
}
}
$breadcrumbs = array();
foreach ($ancestor_handles as $ancestor_handle) {
$breadcrumbs[] = $ancestor_handle->renderLink();
}
$list = phutil_render_tag(
'a',
array(
'href' => '/phriction/',
),
'Document Index');
return
'<div class="phriction-breadcrumbs">'.
$list.' &middot; '.
'<span class="phriction-document-crumbs">'.
implode(" \xC2\xBB ", $breadcrumbs).
'</span>'.
'</div>';
}
+ 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[] = '<ul>';
+ foreach ($children as $child) {
+ $list[] = $this->renderChildDocumentLink($child);
+ $grand = idx($grandchildren, $child['slug'], array());
+ if ($grand) {
+ $list[] = '<ul>';
+ foreach ($grand as $grandchild) {
+ $list[] = $this->renderChildDocumentLink($grandchild);
+ }
+ $list[] = '</ul>';
+ }
+ }
+ if ($more_children) {
+ $list[] = '<li>More...</li>';
+ }
+ $list[] = '</ul>';
+ $list = implode("\n", $list);
+
+ return
+ '<div class="phriction-children">'.
+ '<div class="phriction-children-header">Document Hierarchy</div>'.
+ $list.
+ '</div>';
+ }
+
+ 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 = '<em>'.$item.'</em>';
+ }
+
+ return '<li>'.$item.'</li>';
+ }
+
}
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
@@ -1,25 +1,26 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/markup/engine');
phutil_require_module('phabricator', 'applications/phid/handle');
phutil_require_module('phabricator', 'applications/phid/handle/data');
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');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhrictionDocumentController.php');
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
@@ -1,40 +1,58 @@
/**
* @provides phriction-document-css
*/
.phriction-header {
background: #eeeeee;
border-bottom: 1px solid #dddddd;
padding: 1em;
}
.phriction-header a.button {
float: right;
}
.phriction-header h1 {
margin: .25em 0;
}
.phriction-content {
max-width: 960px;
margin: 1em;
}
.phriction-byline {
padding: .25em 0 1em;
color: #444444;
}
.phriction-content .phriction-link {
font-weight: bold;
}
.phriction-breadcrumbs {
font-size: 12px;
color: #666666;
}
.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;
+}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jul 27, 8:49 PM (1 w, 7 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
186131
Default Alt Text
(12 KB)

Event Timeline