Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/phriction/controller/PhrictionDocumentController.php b/src/applications/phriction/controller/PhrictionDocumentController.php
index 7b7a88fd98..97b328bd67 100644
--- a/src/applications/phriction/controller/PhrictionDocumentController.php
+++ b/src/applications/phriction/controller/PhrictionDocumentController.php
@@ -1,358 +1,369 @@
<?php
/**
* @group phriction
*/
final 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 = PhabricatorSlug::normalize($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);
$version_note = null;
if (!$document) {
$document = new PhrictionDocument();
if (PhrictionDocument::isProjectSlug($slug)) {
$project = id(new PhabricatorProject())->loadOneWhere(
'phrictionSlug = %s',
PhrictionDocument::getProjectSlugIdentifier($slug));
if (!$project) {
return new Aphront404Response();
}
}
$create_uri = '/phriction/edit/?slug='.$slug;
$create_sentence =
'You can <strong>'.
phutil_render_tag(
'a',
array(
'href' => $create_uri,
),
'create a new document').
'</strong>.';
$button = phutil_render_tag(
'a',
array(
'href' => $create_uri,
'class' => 'green button',
),
'Create Page');
$page_content =
'<div class="phriction-content">'.
'<em>No content here!</em><br />'.
'No document found at <tt>'.phutil_escape_html($slug).'</tt>. '.
$create_sentence.
'</div>';
$page_title = 'Page Not Found';
$buttons = $button;
} 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();
$project_phid = null;
if (PhrictionDocument::isProjectSlug($slug)) {
$project = id(new PhabricatorProject())->loadOneWhere(
'phrictionSlug = %s',
PhrictionDocument::getProjectSlugIdentifier($slug));
if ($project) {
$project_phid = $project->getPHID();
}
}
$phids = array_filter(
array(
$content->getAuthorPHID(),
$project_phid,
));
$handles = $this->loadViewerHandles($phids);
$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";
}
$project_info = null;
if ($project_phid) {
$project_info =
'<br />This document is about the project '.
$handles[$project_phid]->renderLink().'.';
}
$index_link = phutil_render_tag(
'a',
array(
'href' => '/phriction/',
),
pht('Document Index'));
$byline =
'<div class="phriction-byline">'.
"Last updated {$when} by ".
$handles[$content->getAuthorPHID()]->renderLink().'.'.
$project_info.
'</div>';
$doc_status = $document->getStatus();
if ($doc_status == PhrictionDocumentStatus::STATUS_EXISTS) {
$core_content = $content->renderContent($user);
} else if ($doc_status == PhrictionDocumentStatus::STATUS_DELETED) {
$notice = new AphrontErrorView();
$notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$notice->setTitle('Document Deleted');
$notice->appendChild(
'This document has been deleted. You can edit it to put new content '.
'here, or use history to revert to an earlier version.');
$core_content = $notice->render();
} else {
throw new Exception("Unknown document status '{$doc_status}'!");
}
$page_content =
'<div class="phriction-content">'.
$index_link.
$byline.
$core_content.
'</div>';
}
if ($version_note) {
$version_note = $version_note->render();
}
$children = $this->renderChildren($slug);
$crumbs = $this->buildApplicationCrumbs();
$crumb_views = $this->renderBreadcrumbs($slug);
foreach ($crumb_views as $view) {
$crumbs->addCrumb($view);
}
$actions = $this->buildActionView($user, $document);
$header = id(new PhabricatorHeaderView())
->setHeader($page_title);
$page =
$crumbs->render().
$header->render().
$actions->render().
$version_note.
$page_content.
$children;
return $this->buildApplicationPage(
array(
$page,
),
array(
'title' => $page_title,
'device' => true,
));
}
private function buildActionView(
PhabricatorUser $user,
PhrictionDocument $document) {
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$document,
PhabricatorPolicyCapability::CAN_EDIT);
$slug = PhabricatorSlug::normalize($this->slug);
- return id(new PhabricatorActionListView())
+ $action_view = id(new PhabricatorActionListView())
->setUser($user)
->setObject($document)
->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Document'))
->setIcon('edit')
- ->setHref('/phriction/edit/'.$document->getID().'/'))
- ->addAction(
+ ->setHref('/phriction/edit/'.$document->getID().'/'));
+
+ if ($document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS) {
+ $action_view->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Delete Document'))
+ ->setIcon('delete')
+ ->setHref('/phriction/delete/'.$document->getID().'/')
+ ->setWorkflow(true));
+ }
+
+ return
+ $action_view->addAction(
id(new PhabricatorActionView())
- ->setName(pht('View History'))
- ->setIcon('history')
- ->setHref(PhrictionDocument::getSlugURI($slug, 'history')));
+ ->setName(pht('View History'))
+ ->setIcon('history')
+ ->setHref(PhrictionDocument::getSlugURI($slug, 'history')));
}
private function renderChildren($slug) {
$document_dao = new PhrictionDocument();
$content_dao = new PhrictionContent();
$conn = $document_dao->establishConnection('r');
$limit = 50;
$d_child = PhabricatorSlug::getDepth($slug) + 1;
$d_grandchild = PhabricatorSlug::getDepth($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)
AND d.status = %d
ORDER BY d.depth, c.title LIMIT %d',
$document_dao->getTableName(),
$content_dao->getTableName(),
($slug == '/' ? '' : $slug),
$d_child,
$d_grandchild,
PhrictionDocumentStatus::STATUS_EXISTS,
$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 = PhabricatorSlug::getAncestry($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' => PhabricatorSlug::getDefaultTitle($slug),
'empty' => true,
);
}
}
$children = isort($children, 'title');
$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) {
$title = nonempty($info['title'], '(Untitled Document)');
$item = phutil_render_tag(
'a',
array(
'href' => PhrictionDocument::getSlugURI($info['slug']),
),
phutil_escape_html($title));
if (isset($info['empty'])) {
$item = '<em>'.$item.'</em>';
}
return '<li>'.$item.'</li>';
}
}
diff --git a/src/applications/phriction/controller/PhrictionEditController.php b/src/applications/phriction/controller/PhrictionEditController.php
index e5ebe1bf11..2c35ce4bed 100644
--- a/src/applications/phriction/controller/PhrictionEditController.php
+++ b/src/applications/phriction/controller/PhrictionEditController.php
@@ -1,279 +1,265 @@
<?php
/**
* @group phriction
*/
final class PhrictionEditController
extends PhrictionController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
if ($this->id) {
$document = id(new PhrictionDocument())->load($this->id);
if (!$document) {
return new Aphront404Response();
}
$revert = $request->getInt('revert');
if ($revert) {
$content = id(new PhrictionContent())->loadOneWhere(
'documentID = %d AND version = %d',
$document->getID(),
$revert);
if (!$content) {
return new Aphront404Response();
}
} else {
$content = id(new PhrictionContent())->load($document->getContentID());
}
} else {
$slug = $request->getStr('slug');
$slug = PhabricatorSlug::normalize($slug);
if (!$slug) {
return new Aphront404Response();
}
$document = id(new PhrictionDocument())->loadOneWhere(
'slug = %s',
$slug);
if ($document) {
$content = id(new PhrictionContent())->load($document->getContentID());
} else {
if (PhrictionDocument::isProjectSlug($slug)) {
$project = id(new PhabricatorProject())->loadOneWhere(
'phrictionSlug = %s',
PhrictionDocument::getProjectSlugIdentifier($slug));
if (!$project) {
return new Aphront404Response();
}
}
$document = new PhrictionDocument();
$document->setSlug($slug);
$content = new PhrictionContent();
$content->setSlug($slug);
$default_title = PhabricatorSlug::getDefaultTitle($slug);
$content->setTitle($default_title);
}
}
if ($request->getBool('nodraft')) {
$draft = null;
$draft_key = null;
} else {
if ($document->getPHID()) {
$draft_key = $document->getPHID().':'.$content->getVersion();
} else {
$draft_key = 'phriction:'.$content->getSlug();
}
$draft = id(new PhabricatorDraft())->loadOneWhere(
'authorPHID = %s AND draftKey = %s',
$user->getPHID(),
$draft_key);
}
require_celerity_resource('phriction-document-css');
$e_title = true;
$notes = null;
$errors = array();
if ($request->isFormPost()) {
$title = $request->getStr('title');
$notes = $request->getStr('description');
if (!strlen($title)) {
$e_title = 'Required';
$errors[] = 'Document title is required.';
} else {
$e_title = null;
}
if ($document->getID()) {
if ($content->getTitle() == $title &&
$content->getContent() == $request->getStr('content')) {
$dialog = new AphrontDialogView();
$dialog->setUser($user);
$dialog->setTitle('No Edits');
$dialog->appendChild(
'<p>You did not make any changes to the document.</p>');
$dialog->addCancelButton($request->getRequestURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
}
} else if (!strlen($request->getStr('content'))) {
// We trigger this only for new pages. For existing pages, deleting
// all the content counts as deleting the page.
$dialog = new AphrontDialogView();
$dialog->setUser($user);
$dialog->setTitle('Empty Page');
$dialog->appendChild(
'<p>You can not create an empty document.</p>');
$dialog->addCancelButton($request->getRequestURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
}
if (!count($errors)) {
$editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))
->setActor($user)
->setTitle($title)
->setContent($request->getStr('content'))
->setDescription($notes);
$editor->save();
if ($draft) {
$draft->delete();
}
$uri = PhrictionDocument::getSlugURI($document->getSlug());
return id(new AphrontRedirectResponse())->setURI($uri);
}
}
$error_view = null;
if ($errors) {
$error_view = id(new AphrontErrorView())
->setTitle('Form Errors')
->setErrors($errors);
}
- $delete_button = null;
if ($document->getID()) {
$panel_header = 'Edit Phriction Document';
$submit_button = 'Save Changes';
- if ($document->getStatus() != PhrictionDocumentStatus::STATUS_DELETED) {
- $delete_button = phutil_render_tag(
- 'a',
- array(
- 'href' => '/phriction/delete/'.$document->getID().'/',
- 'class' => 'grey button',
- ),
- 'Delete Document');
- }
} else {
$panel_header = 'Create New Phriction Document';
$submit_button = 'Create Document';
}
$uri = $document->getSlug();
$uri = PhrictionDocument::getSlugURI($uri);
$uri = PhabricatorEnv::getProductionURI($uri);
$cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());
if ($draft &&
strlen($draft->getDraft()) &&
($draft->getDraft() != $content->getContent())) {
$content_text = $draft->getDraft();
$discard = phutil_render_tag(
'a',
array(
'href' => $request->getRequestURI()->alter('nodraft', true),
),
'discard this draft');
$draft_note = new AphrontErrorView();
$draft_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$draft_note->setTitle('Recovered Draft');
$draft_note->appendChild(
'<p>Showing a saved draft of your edits, you can '.$discard.'.</p>');
} else {
$content_text = $content->getContent();
$draft_note = null;
}
$form = id(new AphrontFormView())
->setUser($user)
->setWorkflow(true)
->setAction($request->getRequestURI()->getPath())
->addHiddenInput('slug', $document->getSlug())
->addHiddenInput('nodraft', $request->getBool('nodraft'))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Title')
->setValue($content->getTitle())
->setError($e_title)
->setName('title'))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('URI')
->setValue($uri))
->appendChild(
id(new PhabricatorRemarkupControl())
->setLabel('Content')
->setValue($content_text)
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)
->setName('content')
->setID('document-textarea')
->setUser($user))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Edit Notes')
->setValue($notes)
->setError(null)
->setName('description'))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($submit_button));
$panel = id(new AphrontPanelView())
->setWidth(AphrontPanelView::WIDTH_WIDE)
->setHeader($panel_header)
->appendChild($form);
- if ($delete_button) {
- $panel->addButton($delete_button);
- }
-
$preview_panel =
'<div class="aphront-panel-preview aphront-panel-preview-wide">
<div class="phriction-document-preview-header">
Document Preview
</div>
<div id="document-preview">
<div class="aphront-panel-preview-loading-text">
Loading preview...
</div>
</div>
</div>';
Javelin::initBehavior(
'phriction-document-preview',
array(
'preview' => 'document-preview',
'textarea' => 'document-textarea',
'uri' => '/phriction/preview/?draftkey='.$draft_key,
));
return $this->buildStandardPageResponse(
array(
$draft_note,
$error_view,
$panel,
$preview_panel,
),
array(
'title' => 'Edit Document',
));
}
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jul 28, 1:18 AM (1 w, 20 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
186315
Default Alt Text
(19 KB)

Event Timeline