diff --git a/src/applications/phriction/controller/PhrictionEditController.php b/src/applications/phriction/controller/PhrictionEditController.php index 2c35ce4bed..f701839262 100644 --- a/src/applications/phriction/controller/PhrictionEditController.php +++ b/src/applications/phriction/controller/PhrictionEditController.php @@ -1,265 +1,265 @@ 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( '

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('Empty Page'); $dialog->appendChild( '

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); } } $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); $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( '

Showing a saved draft of your edits, you can '.$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')) ->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) + ->setNoBackground() ->setHeader($panel_header) ->appendChild($form); $preview_panel = '
Document Preview
Loading preview...
'; 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', )); } } diff --git a/src/applications/phriction/controller/PhrictionHistoryController.php b/src/applications/phriction/controller/PhrictionHistoryController.php index 35cc7e1a44..e6bb0a9aa1 100644 --- a/src/applications/phriction/controller/PhrictionHistoryController.php +++ b/src/applications/phriction/controller/PhrictionHistoryController.php @@ -1,151 +1,152 @@ slug = $data['slug']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $document = id(new PhrictionDocument())->loadOneWhere( 'slug = %s', PhabricatorSlug::normalize($this->slug)); if (!$document) { return new Aphront404Response(); } $current = id(new PhrictionContent())->load($document->getContentID()); $pager = new AphrontPagerView(); $pager->setOffset($request->getInt('page')); $pager->setURI($request->getRequestURI(), 'page'); $history = id(new PhrictionContent())->loadAllWhere( 'documentID = %d ORDER BY version DESC LIMIT %d, %d', $document->getID(), $pager->getOffset(), $pager->getPageSize() + 1); $history = $pager->sliceResults($history); $author_phids = mpull($history, 'getAuthorPHID'); $handles = $this->loadViewerHandles($author_phids); $rows = array(); foreach ($history as $content) { $slug_uri = PhrictionDocument::getSlugURI($document->getSlug()); $version = $content->getVersion(); $diff_uri = new PhutilURI('/phriction/diff/'.$document->getID().'/'); $vs_previous = 'Created'; if ($content->getVersion() != 1) { $uri = $diff_uri ->alter('l', $content->getVersion() - 1) ->alter('r', $content->getVersion()); $vs_previous = phutil_render_tag( 'a', array( 'href' => $uri, ), 'Show Change'); } $vs_head = 'Current'; if ($content->getID() != $document->getContentID()) { $uri = $diff_uri ->alter('l', $content->getVersion()) ->alter('r', $current->getVersion()); $vs_head = phutil_render_tag( 'a', array( 'href' => $uri, ), 'Show Later Changes'); } $change_type = PhrictionChangeType::getChangeTypeLabel( $content->getChangeType()); $rows[] = array( phabricator_date($content->getDateCreated(), $user), phabricator_time($content->getDateCreated(), $user), phutil_render_tag( 'a', array( 'href' => $slug_uri.'?v='.$version, ), 'Version '.$version), $handles[$content->getAuthorPHID()]->renderLink(), $change_type, phutil_escape_html($content->getDescription()), $vs_previous, $vs_head, ); } $table = new AphrontTableView($rows); $table->setHeaders( array( 'Date', 'Time', 'Version', 'Author', 'Type', 'Description', 'Against Previous', 'Against Current', )); $table->setColumnClasses( array( '', 'right', 'pri', '', '', 'wide', '', '', )); $crumbs = $this->buildApplicationCrumbs(); $crumb_views = $this->renderBreadcrumbs($document->getSlug()); foreach ($crumb_views as $view) { $crumbs->addCrumb($view); } $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('History')) ->setHref( PhrictionDocument::getSlugURI($document->getSlug(), 'history'))); $panel = new AphrontPanelView(); $panel->setHeader('Document History'); + $panel->setNoBackground(); $panel->appendChild($table); $panel->appendChild($pager); return $this->buildApplicationPage( array( $crumbs, $panel, ), array( 'title' => 'Document History', 'device' => true, )); } } diff --git a/src/applications/phriction/controller/PhrictionListController.php b/src/applications/phriction/controller/PhrictionListController.php index abd90432e9..269a70288c 100644 --- a/src/applications/phriction/controller/PhrictionListController.php +++ b/src/applications/phriction/controller/PhrictionListController.php @@ -1,160 +1,161 @@ 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]); $nav->appendChild( array( $header, )); $pager = new AphrontPagerView(); $pager->setURI($request->getRequestURI(), 'page'); $pager->setOffset($request->getInt('page')); $documents = $this->loadDocuments($pager); $content = mpull($documents, 'getContent'); $phids = mpull($content, 'getAuthorPHID'); $handles = $this->loadViewerHandles($phids); $rows = array(); foreach ($documents as $document) { $content = $document->getContent(); $rows[] = array( $handles[$content->getAuthorPHID()]->renderLink(), phutil_render_tag( 'a', array( 'href' => PhrictionDocument::getSlugURI($document->getSlug()), ), phutil_escape_html($content->getTitle())), phabricator_date($content->getDateCreated(), $user), phabricator_time($content->getDateCreated(), $user), ); } $document_table = new AphrontTableView($rows); $document_table->setHeaders( array( 'Last Editor', 'Title', 'Last Update', 'Time', )); $document_table->setColumnClasses( array( '', 'wide pri', 'right', 'right', )); $view_header = $views[$this->view]; $panel = new AphrontPanelView(); + $panel->setNoBackground(); $panel->appendChild($document_table); $panel->appendChild($pager); $nav->appendChild($panel); return $this->buildApplicationPage( $nav, array( 'title' => pht('Phriction Main'), )); } private function loadDocuments(AphrontPagerView $pager) { // TODO: Do we want/need a query object for this? $document_dao = new PhrictionDocument(); $content_dao = new PhrictionContent(); $conn = $document_dao->establishConnection('r'); switch ($this->view) { case 'active': $data = queryfx_all( $conn, 'SELECT * FROM %T WHERE status != %d ORDER BY id DESC LIMIT %d, %d', $document_dao->getTableName(), PhrictionDocumentStatus::STATUS_DELETED, $pager->getOffset(), $pager->getPageSize() + 1); break; case 'all': $data = queryfx_all( $conn, 'SELECT * FROM %T ORDER BY id DESC LIMIT %d, %d', $document_dao->getTableName(), $pager->getOffset(), $pager->getPageSize() + 1); break; case 'updates': // TODO: This query is a little suspicious, verify we don't need to key // or change it once we get more data. $data = queryfx_all( $conn, 'SELECT d.* FROM %T d JOIN %T c ON c.documentID = d.id GROUP BY c.documentID ORDER BY MAX(c.id) DESC LIMIT %d, %d', $document_dao->getTableName(), $content_dao->getTableName(), $pager->getOffset(), $pager->getPageSize() + 1); break; default: throw new Exception("Unknown view '{$this->view}'!"); } $data = $pager->sliceResults($data); $documents = $document_dao->loadAllFromArray($data); if ($documents) { $content = $content_dao->loadAllWhere( 'documentID IN (%Ld)', mpull($documents, 'getID')); $content = mpull($content, null, 'getDocumentID'); foreach ($documents as $document) { $document->attachContent($content[$document->getID()]); } } return $documents; } }