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 {
             $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;
     $errors = array();
     if ($request->isFormPost()) {
         $title = $request->getStr('title');
         if (!strlen($title)) {
             $e_title = 'Required';
             $errors[] = 'Document title is required.';
         } else {
             $e_title = null;
         }
         if (!count($errors)) {
             $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))->setUser($user)->setTitle($title)->setContent($request->getStr('content'))->setDescription($request->getStr('description'));
             $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);
     }
     if ($document->getID()) {
         $panel_header = 'Edit Phriction Document';
         $submit_button = 'Save Changes';
         $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';
         $delete_button = null;
     }
     $uri = $document->getSlug();
     $uri = PhrictionDocument::getSlugURI($uri);
     $uri = PhabricatorEnv::getProductionURI($uri);
     $remarkup_reference = phutil_render_tag('a', array('href' => PhabricatorEnv::getDoclink('article/Remarkup_Reference.html'), 'tabindex' => '-1', 'target' => '_blank'), 'Formatting Reference');
     $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)->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 AphrontFormTextAreaControl())->setLabel('Content')->setValue($content_text)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('content')->setID('document-textarea')->setEnableDragAndDropFileUploads(true)->setCaption($remarkup_reference))->appendChild(id(new AphrontFormTextControl())->setLabel('Edit Notes')->setValue($content->getDescription())->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'));
 }
 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 PhrictionDocumentQuery())->setViewer($user)->withSlugs(array($slug))->executeOne();
     $version_note = null;
     $core_content = '';
     $move_notice = '';
     $properties = null;
     if (!$document) {
         $document = new PhrictionDocument();
         if (PhrictionDocument::isProjectSlug($slug)) {
             $project = id(new PhabricatorProjectQuery())->setViewer($user)->withPhrictionSlugs(array(PhrictionDocument::getProjectSlugIdentifier($slug)))->executeOne();
             if (!$project) {
                 return new Aphront404Response();
             }
         }
         $create_uri = '/phriction/edit/?slug=' . $slug;
         $notice = new AphrontErrorView();
         $notice->setSeverity(AphrontErrorView::SEVERITY_NODATA);
         $notice->setTitle(pht('No content here!'));
         $notice->appendChild(pht('No document found at %s. You can <strong>' . '<a href="%s">create a new document here</a></strong>.', phutil_tag('tt', array(), $slug), $create_uri));
         $core_content = $notice;
         $page_title = pht('Page Not Found');
     } 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()) {
                 $vdate = phabricator_datetime($content->getDateCreated(), $user);
                 $version_note = new AphrontErrorView();
                 $version_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
                 $version_note->appendChild(pht('You are viewing an older version of this document, as it ' . 'appeared on %s.', $vdate));
             }
         } else {
             $content = id(new PhrictionContent())->load($document->getContentID());
         }
         $page_title = $content->getTitle();
         $properties = $this->buildPropertyListView($document, $content, $slug);
         $doc_status = $document->getStatus();
         $current_status = $content->getChangeType();
         if ($current_status == PhrictionChangeType::CHANGE_EDIT || $current_status == PhrictionChangeType::CHANGE_MOVE_HERE) {
             $core_content = $content->renderContent($user);
         } else {
             if ($current_status == PhrictionChangeType::CHANGE_DELETE) {
                 $notice = new AphrontErrorView();
                 $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
                 $notice->setTitle(pht('Document Deleted'));
                 $notice->appendChild(pht('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 {
                 if ($current_status == PhrictionChangeType::CHANGE_STUB) {
                     $notice = new AphrontErrorView();
                     $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
                     $notice->setTitle(pht('Empty Document'));
                     $notice->appendChild(pht('This document is empty. You can edit it to put some proper ' . 'content here.'));
                     $core_content = $notice->render();
                 } else {
                     if ($current_status == PhrictionChangeType::CHANGE_MOVE_AWAY) {
                         $new_doc_id = $content->getChangeRef();
                         $slug_uri = null;
                         // If the new document exists and the viewer can see it, provide a link
                         // to it. Otherwise, render a generic message.
                         $new_docs = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($new_doc_id))->execute();
                         if ($new_docs) {
                             $new_doc = head($new_docs);
                             $slug_uri = PhrictionDocument::getSlugURI($new_doc->getSlug());
                         }
                         $notice = id(new AphrontErrorView())->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
                         if ($slug_uri) {
                             $notice->appendChild(phutil_tag('p', array(), pht('This document has been moved to %s. You can edit it to put ' . 'new content here, or use history to revert to an earlier ' . 'version.', phutil_tag('a', array('href' => $slug_uri), $slug_uri))));
                         } else {
                             $notice->appendChild(phutil_tag('p', array(), pht('This document has been moved. You can edit it to put new ' . 'contne here, or use history to revert to an earlier ' . 'version.')));
                         }
                         $core_content = $notice->render();
                     } else {
                         throw new Exception("Unknown document status '{$doc_status}'!");
                     }
                 }
             }
         }
         $move_notice = null;
         if ($current_status == PhrictionChangeType::CHANGE_MOVE_HERE) {
             $from_doc_id = $content->getChangeRef();
             $slug_uri = null;
             // If the old document exists and is visible, provide a link to it.
             $from_docs = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($from_doc_id))->execute();
             if ($from_docs) {
                 $from_doc = head($from_docs);
                 $slug_uri = PhrictionDocument::getSlugURI($from_doc->getSlug());
             }
             $move_notice = id(new AphrontErrorView())->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
             if ($slug_uri) {
                 $move_notice->appendChild(pht('This document was moved from %s.', phutil_tag('a', array('href' => $slug_uri), $slug_uri)));
             } else {
                 // Render this for consistency, even though it's a bit silly.
                 $move_notice->appendChild(pht('This document was moved from elsewhere.'));
             }
         }
     }
     $children = $this->renderDocumentChildren($slug);
     $actions = $this->buildActionView($user, $document);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->setActionList($actions);
     $crumb_views = $this->renderBreadcrumbs($slug);
     foreach ($crumb_views as $view) {
         $crumbs->addCrumb($view);
     }
     $header = id(new PHUIHeaderView())->setHeader($page_title);
     $prop_list = null;
     if ($properties) {
         $prop_list = new PHUIPropertyGroupView();
         $prop_list->addPropertyList($properties);
     }
     $page_content = id(new PHUIDocumentView())->setOffset(true)->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS)->setHeader($header)->appendChild(array($actions, $prop_list, $version_note, $move_notice, $core_content));
     $core_page = phutil_tag('div', array('class' => 'phriction-offset'), array($page_content, $children));
     return $this->buildApplicationPage(array($crumbs->render(), $core_page), array('pageObjects' => array($document->getPHID()), 'title' => $page_title));
 }
Ejemplo n.º 3
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $current_version = null;
     if ($this->id) {
         $document = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($this->id))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$document) {
             return new Aphront404Response();
         }
         $current_version = $document->getContent()->getVersion();
         $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 = $document->getContent();
         }
     } else {
         $slug = $request->getStr('slug');
         $slug = PhabricatorSlug::normalize($slug);
         if (!$slug) {
             return new Aphront404Response();
         }
         $document = id(new PhrictionDocumentQuery())->setViewer($user)->withSlugs(array($slug))->needContent(true)->executeOne();
         if ($document) {
             $content = $document->getContent();
             $current_version = $content->getVersion();
         } else {
             if (PhrictionDocument::isProjectSlug($slug)) {
                 $project = id(new PhabricatorProjectQuery())->setViewer($user)->withPhrictionSlugs(array(PhrictionDocument::getProjectSlugIdentifier($slug)))->executeOne();
                 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()) {
         $overwrite = $request->getBool('overwrite');
         if (!$overwrite) {
             $edit_version = $request->getStr('contentVersion');
             if ($edit_version != $current_version) {
                 $dialog = $this->newDialog()->setTitle(pht('Edit Conflict!'))->appendParagraph(pht('Another user made changes to this document after you began ' . 'editing it. Do you want to overwrite their changes?'))->appendParagraph(pht('If you choose to overwrite their changes, you should review ' . 'the document edit history to see what you overwrote, and ' . 'then make another edit to merge the changes if necessary.'))->addSubmitButton(pht('Overwrite Changes'))->addCancelButton($request->getRequestURI());
                 $dialog->addHiddenInput('overwrite', 'true');
                 foreach ($request->getPassthroughRequestData() as $key => $value) {
                     $dialog->addHiddenInput($key, $value);
                 }
                 return $dialog;
             }
         }
         $title = $request->getStr('title');
         $notes = $request->getStr('description');
         if (!strlen($title)) {
             $e_title = pht('Required');
             $errors[] = pht('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(pht('No Edits'));
                 $dialog->appendChild(phutil_tag('p', array(), pht('You did not make any changes to the document.')));
                 $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(pht('Empty Page'));
                 $dialog->appendChild(phutil_tag('p', array(), pht('You can not create an empty document.')));
                 $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);
         }
     }
     if ($document->getID()) {
         $panel_header = pht('Edit Phriction Document');
         $submit_button = pht('Save Changes');
     } else {
         $panel_header = pht('Create New Phriction Document');
         $submit_button = pht('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_tag('a', array('href' => $request->getRequestURI()->alter('nodraft', true)), pht('discard this draft'));
         $draft_note = new AphrontErrorView();
         $draft_note->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
         $draft_note->setTitle('Recovered Draft');
         $draft_note->appendChild(hsprintf('<p>Showing a saved draft of your edits, you can %s.</p>', $discard));
     } 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'))->addHiddenInput('contentVersion', $current_version)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Title'))->setValue($content->getTitle())->setError($e_title)->setName('title'))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('URI'))->setValue($uri))->appendChild(id(new PhabricatorRemarkupControl())->setLabel(pht('Content'))->setValue($content_text)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('content')->setID('document-textarea')->setUser($user))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Edit Notes'))->setValue($notes)->setError(null)->setName('description'))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_button));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Edit Document'))->setFormErrors($errors)->setForm($form);
     $preview = id(new PHUIRemarkupPreviewPanel())->setHeader(pht('Document Preview'))->setPreviewURI('/phriction/preview/')->setControlID('document-textarea')->setSkin('document');
     $crumbs = $this->buildApplicationCrumbs();
     if ($document->getID()) {
         $crumbs->addTextCrumb($content->getTitle(), PhrictionDocument::getSlugURI($document->getSlug()));
         $crumbs->addTextCrumb(pht('Edit'));
     } else {
         $crumbs->addTextCrumb(pht('Create'));
     }
     return $this->buildApplicationPage(array($crumbs, $draft_note, $form_box, $preview), array('title' => pht('Edit Document')));
 }
 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 = PhrictionDocument::normalizeSlug($slug);
         if (!$slug) {
             return new Aphront404Response();
         }
         $document = id(new PhrictionDocument())->loadOneWhere('slug = %s', $slug);
         if ($document) {
             $content = id(new PhrictionContent())->load($document->getContentID());
         } else {
             $document = new PhrictionDocument();
             $document->setSlug($slug);
             $content = new PhrictionContent();
             $content->setSlug($slug);
             $default_title = PhrictionDocument::getDefaultSlugTitle($slug);
             $content->setTitle($default_title);
         }
     }
     require_celerity_resource('phriction-document-css');
     $e_title = true;
     $errors = array();
     if ($request->isFormPost()) {
         $title = $request->getStr('title');
         if (!strlen($title)) {
             $e_title = 'Required';
             $errors[] = 'Document title is required.';
         } else {
             $e_title = null;
         }
         if (!count($errors)) {
             $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))->setUser($user)->setTitle($title)->setContent($request->getStr('content'))->setDescription($request->getStr('description'));
             $editor->save();
             $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);
     }
     if ($document->getID()) {
         $panel_header = 'Edit Phriction Document';
         $submit_button = 'Save Changes';
     } else {
         $panel_header = 'Create New Phriction Document';
         $submit_button = 'Create Document';
     }
     $uri = $document->getSlug();
     $uri = PhrictionDocument::getSlugURI($uri);
     $uri = PhabricatorEnv::getProductionURI($uri);
     $remarkup_reference = phutil_render_tag('a', array('href' => PhabricatorEnv::getDoclink('article/Remarkup_Reference.html')), 'Formatting Reference');
     $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());
     $form = id(new AphrontFormView())->setUser($user)->setAction($request->getRequestURI()->getPath())->addHiddenInput('slug', $document->getSlug())->appendChild(id(new AphrontFormTextControl())->setLabel('Title')->setValue($content->getTitle())->setError($e_title)->setName('title'))->appendChild(id(new AphrontFormTextControl())->setLabel('Description')->setValue($content->getDescription())->setError(null)->setName('description'))->appendChild(id(new AphrontFormStaticControl())->setLabel('URI')->setValue($uri))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Content')->setValue($content->getContent())->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('content')->setID('document-textarea')->setEnableDragAndDropFileUploads(true)->setCaption($remarkup_reference))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_button));
     $panel = id(new AphrontPanelView())->setWidth(AphrontPanelView::WIDTH_WIDE)->setHeader($panel_header)->appendChild($form);
     $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/'));
     return $this->buildStandardPageResponse(array($error_view, $panel, $preview_panel), array('title' => 'Edit Document'));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $slug = $request->getStr('slug');
     $slug = PhrictionDocument::normalizeSlug($slug);
     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 {
         if ($slug) {
             $document = id(new PhrictionDocument())->loadOneWhere('slug = %s', $slug);
             if ($document) {
                 $content = id(new PhrictionContent())->load($document->getContentID());
             } else {
                 $document = new PhrictionDocument();
                 $document->setSlug($slug);
                 $content = new PhrictionContent();
                 $content->setSlug($slug);
                 $default_title = PhrictionDocument::getDefaultSlugTitle($slug);
                 $content->setTitle($default_title);
             }
         } else {
             return new Aphront404Response();
         }
     }
     require_celerity_resource('phriction-document-css');
     $e_title = true;
     $errors = array();
     if ($request->isFormPost()) {
         $title = $request->getStr('title');
         if (!strlen($title)) {
             $e_title = 'Required';
             $errors[] = 'Document title is required.';
         } else {
             $e_title = null;
         }
         if (!count($errors)) {
             // TODO: This should all be transactional.
             $is_new = false;
             if (!$document->getID()) {
                 $is_new = true;
                 $document->save();
             }
             $new_content = new PhrictionContent();
             $new_content->setSlug($document->getSlug());
             $new_content->setTitle($title);
             $new_content->setDescription($request->getStr('description'));
             $new_content->setContent($request->getStr('content'));
             $new_content->setDocumentID($document->getID());
             $new_content->setVersion($content->getVersion() + 1);
             $new_content->setAuthorPHID($user->getPHID());
             $new_content->save();
             $document->setContentID($new_content->getID());
             $document->save();
             $document->attachContent($new_content);
             PhabricatorSearchPhrictionIndexer::indexDocument($document);
             id(new PhabricatorFeedStoryPublisher())->setRelatedPHIDs(array($document->getPHID(), $user->getPHID()))->setStoryAuthorPHID($user->getPHID())->setStoryTime(time())->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_PHRICTION)->setStoryData(array('phid' => $document->getPHID(), 'action' => $is_new ? PhrictionActionConstants::ACTION_CREATE : PhrictionActionConstants::ACTION_EDIT, 'content' => phutil_utf8_shorten($new_content->getContent(), 140)))->publish();
             $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);
     }
     if ($document->getID()) {
         $panel_header = 'Edit Phriction Document';
         $submit_button = 'Save Changes';
     } else {
         $panel_header = 'Create New Phriction Document';
         $submit_button = 'Create Document';
     }
     $uri = $document->getSlug();
     $uri = PhrictionDocument::getSlugURI($uri);
     $uri = PhabricatorEnv::getProductionURI($uri);
     $remarkup_reference = phutil_render_tag('a', array('href' => PhabricatorEnv::getDoclink('article/Remarkup_Reference.html')), 'Formatting Reference');
     $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());
     $form = id(new AphrontFormView())->setUser($user)->setAction($request->getRequestURI()->getPath())->addHiddenInput('slug', $slug)->appendChild(id(new AphrontFormTextControl())->setLabel('Title')->setValue($content->getTitle())->setError($e_title)->setName('title'))->appendChild(id(new AphrontFormTextControl())->setLabel('Description')->setValue($content->getDescription())->setError(null)->setName('description'))->appendChild(id(new AphrontFormStaticControl())->setLabel('URI')->setValue($uri))->appendChild(id(new AphrontFormTextAreaControl())->setLabel('Content')->setValue($content->getContent())->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('content')->setID('document-textarea')->setCaption($remarkup_reference))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_button));
     $panel = id(new AphrontPanelView())->setWidth(AphrontPanelView::WIDTH_WIDE)->setHeader($panel_header)->appendChild($form);
     $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/'));
     return $this->buildStandardPageResponse(array($error_view, $panel, $preview_panel), array('title' => 'Edit Document'));
 }