Ejemplo n.º 1
0
 protected function renderResultList(array $documents, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($documents, 'PhrictionDocument');
     $viewer = $this->requireViewer();
     $list = new PHUIObjectItemListView();
     $list->setUser($viewer);
     foreach ($documents as $document) {
         $content = $document->getContent();
         $slug = $document->getSlug();
         $author_phid = $content->getAuthorPHID();
         $slug_uri = PhrictionDocument::getSlugURI($slug);
         $byline = pht('Edited by %s', $handles[$author_phid]->renderLink());
         $updated = phabricator_datetime($content->getDateCreated(), $viewer);
         $item = id(new PHUIObjectItemView())->setHeader($content->getTitle())->setHref($slug_uri)->addByline($byline)->addIcon('none', $updated);
         $item->addAttribute($slug_uri);
         switch ($document->getStatus()) {
             case PhrictionDocumentStatus::STATUS_DELETED:
                 $item->setDisabled(true);
                 $item->addIcon('delete', pht('Deleted'));
                 break;
             case PhrictionDocumentStatus::STATUS_MOVED:
                 $item->setDisabled(true);
                 $item->addIcon('arrow-right', pht('Moved Away'));
                 break;
         }
         $list->addItem($item);
     }
     $result = new PhabricatorApplicationSearchResultView();
     $result->setObjectList($list);
     $result->setNoDataString(pht('No documents found.'));
     return $result;
 }
 protected final function buildDocumentContentDictionary(PhrictionDocument $doc, PhrictionContent $content)
 {
     $uri = PhrictionDocument::getSlugURI($content->getSlug());
     $uri = PhabricatorEnv::getProductionURI($uri);
     $doc_status = $doc->getStatus();
     return array('phid' => $doc->getPHID(), 'uri' => $uri, 'slug' => $content->getSlug(), 'version' => $content->getVersion(), 'authorPHID' => $content->getAuthorPHID(), 'title' => $content->getTitle(), 'content' => $content->getContent(), 'status' => PhrictionDocumentStatus::getConduitConstant($doc_status), 'description' => $content->getDescription(), 'dateCreated' => $content->getDateCreated());
 }
 public function markupDocumentLink($matches)
 {
     $slug = trim($matches[1]);
     $name = trim(idx($matches, 2, $slug));
     // If whatever is being linked to begins with "/" or has "://", treat it
     // as a URI instead of a wiki page.
     $is_uri = preg_match('@(^/)|(://)@', $slug);
     if ($is_uri) {
         $protocols = $this->getEngine()->getConfig('uri.allowed-protocols', array());
         $protocol = id(new PhutilURI($slug))->getProtocol();
         if (!idx($protocols, $protocol)) {
             // Don't treat this as a URI if it's not an allowed protocol.
             $is_uri = false;
         }
     }
     if ($is_uri) {
         $uri = $slug;
         // Leave the name unchanged, i.e. link the whole URI if there's no
         // explicit name.
     } else {
         $name = explode('/', trim($name, '/'));
         $name = end($name);
         $slug = PhrictionDocument::normalizeSlug($slug);
         $uri = PhrictionDocument::getSlugURI($slug);
     }
     return $this->getEngine()->storeText(phutil_render_tag('a', array('href' => $uri, 'class' => $is_uri ? null : 'phriction-link'), phutil_escape_html($name)));
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $document = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_VIEW))->executeOne();
     if (!$document) {
         return new Aphront404Response();
     }
     $e_text = null;
     $disallowed_states = array(PhrictionDocumentStatus::STATUS_DELETED => true, PhrictionDocumentStatus::STATUS_MOVED => true, PhrictionDocumentStatus::STATUS_STUB => true);
     if (isset($disallowed_states[$document->getStatus()])) {
         $e_text = pht('An already moved or deleted document can not be deleted');
     }
     $document_uri = PhrictionDocument::getSlugURI($document->getSlug());
     if (!$e_text && $request->isFormPost()) {
         $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))->setActor($user)->delete();
         return id(new AphrontRedirectResponse())->setURI($document_uri);
     }
     if ($e_text) {
         $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Can not delete document!'))->appendChild($e_text)->addCancelButton($document_uri);
     } else {
         $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Delete Document?'))->appendChild(pht('Really delete this document? You can recover it later by ' . 'reverting to a previous version.'))->addSubmitButton(pht('Delete'))->addCancelButton($document_uri);
     }
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
Ejemplo n.º 5
0
 public function renderBreadcrumbs($slug)
 {
     $ancestor_handles = array();
     $ancestral_slugs = PhabricatorSlug::getAncestry($slug);
     $ancestral_slugs[] = $slug;
     if ($ancestral_slugs) {
         $empty_slugs = array_fill_keys($ancestral_slugs, null);
         $ancestors = id(new PhrictionDocumentQuery())->setViewer($this->getRequest()->getUser())->withSlugs($ancestral_slugs)->execute();
         $ancestors = mpull($ancestors, null, 'getSlug');
         $ancestor_phids = mpull($ancestors, 'getPHID');
         $handles = array();
         if ($ancestor_phids) {
             $handles = $this->loadViewerHandles($ancestor_phids);
         }
         $ancestor_handles = array();
         foreach ($ancestral_slugs as $slug) {
             if (isset($ancestors[$slug])) {
                 $ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()];
             } else {
                 $handle = new PhabricatorObjectHandle();
                 $handle->setName(PhabricatorSlug::getDefaultTitle($slug));
                 $handle->setURI(PhrictionDocument::getSlugURI($slug));
                 $ancestor_handles[] = $handle;
             }
         }
     }
     $breadcrumbs = array();
     foreach ($ancestor_handles as $ancestor_handle) {
         $breadcrumbs[] = id(new PHUICrumbView())->setName($ancestor_handle->getName())->setHref($ancestor_handle->getUri());
     }
     return $breadcrumbs;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $document = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($this->id))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT, PhabricatorPolicyCapability::CAN_VIEW))->executeOne();
     if (!$document) {
         return new Aphront404Response();
     }
     $document_uri = PhrictionDocument::getSlugURI($document->getSlug());
     $e_text = null;
     if ($request->isFormPost()) {
         $xactions = array();
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_DELETE)->setNewValue(true);
         $editor = id(new PhrictionTransactionEditor())->setActor($user)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
         try {
             $editor->applyTransactions($document, $xactions);
             return id(new AphrontRedirectResponse())->setURI($document_uri);
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $e_text = phutil_implode_html("\n", $ex->getErrorMessages());
         }
     }
     if ($e_text) {
         $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Can Not Delete Document!'))->appendChild($e_text)->addCancelButton($document_uri);
     } else {
         $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Delete Document?'))->appendChild(pht('Really delete this document? You can recover it later by ' . 'reverting to a previous version.'))->addSubmitButton(pht('Delete'))->addCancelButton($document_uri);
     }
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
Ejemplo n.º 7
0
 public function markupDocumentLink($matches)
 {
     $link = trim($matches[1]);
     $name = trim(idx($matches, 2, $link));
     if (empty($matches[2])) {
         $name = explode('/', trim($name, '/'));
         $name = end($name);
     }
     $uri = new PhutilURI($link);
     $slug = $uri->getPath();
     $fragment = $uri->getFragment();
     $slug = PhabricatorSlug::normalize($slug);
     $slug = PhrictionDocument::getSlugURI($slug);
     $href = (string) id(new PhutilURI($slug))->setFragment($fragment);
     if ($this->getEngine()->getState('toc')) {
         $text = $name;
     } else {
         if ($this->getEngine()->isTextMode()) {
             return PhabricatorEnv::getProductionURI($href);
         } else {
             $text = $this->newTag('a', array('href' => $href, 'class' => 'phriction-link'), $name);
         }
     }
     return $this->getEngine()->storeText($text);
 }
 public function markupDocumentLink($matches)
 {
     $slug = trim($matches[1]);
     $name = trim(idx($matches, 2, $slug));
     $name = explode('/', $name);
     $name = end($name);
     $slug = PhrictionDocument::normalizeSlug($slug);
     $uri = PhrictionDocument::getSlugURI($slug);
     return $this->getEngine()->storeText(phutil_render_tag('a', array('href' => $uri, 'class' => 'phriction-link'), phutil_escape_html($name)));
 }
 public function loadHandles(PhabricatorHandleQuery $query, array $handles, array $objects)
 {
     foreach ($handles as $phid => $handle) {
         $document = $objects[$phid];
         $content = $document->getContent();
         $title = $content->getTitle();
         $slug = $document->getSlug();
         $status = $document->getStatus();
         $handle->setName($title);
         $handle->setURI(PhrictionDocument::getSlugURI($slug));
         if ($status != PhrictionDocumentStatus::STATUS_EXISTS) {
             $handle->setStatus(PhabricatorObjectHandle::STATUS_CLOSED);
         }
     }
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $document = id(new PhrictionDocument())->load($this->id);
     if (!$document) {
         return new Aphront404Response();
     }
     $document_uri = PhrictionDocument::getSlugURI($document->getSlug());
     if ($request->isFormPost()) {
         $editor = id(PhrictionDocumentEditor::newForSlug($document->getSlug()))->setUser($user)->delete();
         return id(new AphrontRedirectResponse())->setURI($document_uri);
     }
     $dialog = id(new AphrontDialogView())->setUser($user)->setTitle('Delete document?')->appendChild('Really delete this document? You can recover it later by reverting ' . 'to a previous version.')->addSubmitButton('Delete')->addCancelButton($document_uri);
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 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 = id(new PhabricatorObjectHandleData($author_phids))->loadHandles();
     $rows = array();
     foreach ($history as $content) {
         $uri = PhrictionDocument::getSlugURI($document->getSlug());
         $version = $content->getVersion();
         $diff_uri = new PhutilURI('/phriction/diff/' . $document->getID() . '/');
         $vs_previous = '<em>Created</em>';
         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 = '<em>Current</em>';
         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' => $uri . '?v=' . $version), 'Version ' . $version), $handles[$content->getAuthorPHID()]->renderLink(), $change_type, phutil_escape_html($content->getDescription()), $vs_previous, $vs_head);
     }
     $crumbs = new AphrontCrumbsView();
     $crumbs->setCrumbs(array('Phriction', phutil_render_tag('a', array('href' => PhrictionDocument::getSlugURI($document->getSlug())), phutil_escape_html($current->getTitle())), 'History'));
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Date', 'Time', 'Version', 'Author', 'Type', 'Description', 'Against Previous', 'Against Current'));
     $table->setColumnClasses(array('', 'right', 'pri', '', '', 'wide', '', ''));
     $panel = new AphrontPanelView();
     $panel->setHeader('Document History');
     $panel->appendChild($table);
     $panel->appendChild($pager);
     return $this->buildStandardPageResponse(array($crumbs, $panel), array('title' => 'Document History'));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $document = id(new PhrictionDocumentQuery())->setViewer($viewer)->withIDs(array($request->getURIData('id')))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$document) {
         return new Aphront404Response();
     }
     $slug = $document->getSlug();
     $cancel_uri = PhrictionDocument::getSlugURI($slug);
     $v_slug = $slug;
     $e_slug = null;
     $v_note = '';
     $validation_exception = null;
     if ($request->isFormPost()) {
         $v_note = $request->getStr('description');
         $v_slug = $request->getStr('slug');
         $normal_slug = PhabricatorSlug::normalize($v_slug);
         // If what the user typed isn't what we're actually using, warn them
         // about it.
         if (strlen($v_slug)) {
             $no_slash_slug = rtrim($normal_slug, '/');
             if ($normal_slug !== $v_slug && $no_slash_slug !== $v_slug) {
                 return $this->newDialog()->setTitle(pht('Adjust Path'))->appendParagraph(pht('The path you entered (%s) is not a valid wiki document ' . 'path. Paths may not contain spaces or special characters.', phutil_tag('strong', array(), $v_slug)))->appendParagraph(pht('Would you like to use the path %s instead?', phutil_tag('strong', array(), $normal_slug)))->addHiddenInput('slug', $normal_slug)->addHiddenInput('description', $v_note)->addCancelButton($cancel_uri)->addSubmitButton(pht('Accept Path'));
             }
         }
         $editor = id(new PhrictionTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setDescription($v_note);
         $xactions = array();
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_MOVE_TO)->setNewValue($document);
         $target_document = id(new PhrictionDocumentQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withSlugs(array($normal_slug))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$target_document) {
             $target_document = PhrictionDocument::initializeNewDocument($viewer, $v_slug);
         }
         try {
             $editor->applyTransactions($target_document, $xactions);
             $redir_uri = PhrictionDocument::getSlugURI($target_document->getSlug());
             return id(new AphrontRedirectResponse())->setURI($redir_uri);
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $validation_exception = $ex;
             $e_slug = $ex->getShortMessage(PhrictionTransaction::TYPE_MOVE_TO);
         }
     }
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Title'))->setValue($document->getContent()->getTitle()))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Current Path'))->setDisabled(true)->setValue($slug))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('New Path'))->setValue($v_slug)->setError($e_slug)->setName('slug'))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Edit Notes'))->setValue($v_note)->setName('description'));
     return $this->newDialog()->setTitle(pht('Move Document'))->setValidationException($validation_exception)->appendForm($form)->addSubmitButton(pht('Move Document'))->addCancelButton($cancel_uri);
 }
Ejemplo n.º 13
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $views = array('all' => 'All Documents', 'updates' => 'Recently Updated');
     if (empty($views[$this->view])) {
         $this->view = 'all';
     }
     $nav = new AphrontSideNavView();
     foreach ($views as $view => $name) {
         $nav->addNavItem(phutil_render_tag('a', array('href' => '/phriction/list/' . $view . '/', 'class' => $this->view == $view ? 'aphront-side-nav-selected' : null), phutil_escape_html($name)));
     }
     $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_headers = array('all' => 'All Documents', 'updates' => 'Recently Updated Documents');
     $view_header = $view_headers[$this->view];
     $panel = new AphrontPanelView();
     $panel->setHeader($view_header);
     $panel->appendChild($document_table);
     $panel->appendChild($pager);
     $nav->appendChild($panel);
     return $this->buildStandardPageResponse($nav, array('title' => 'Phriction Main'));
 }
 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 loadHandles()
 {
     $types = phid_group_by_type($this->phids);
     $handles = array();
     $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
     foreach ($types as $type => $phids) {
         switch ($type) {
             case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
                 // Black magic!
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     switch ($phid) {
                         case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
                             $handle->setName('Up For Grabs');
                             $handle->setFullName('upforgrabs (Up For Grabs)');
                             $handle->setComplete(true);
                             break;
                         case ManiphestTaskOwner::PROJECT_NO_PROJECT:
                             $handle->setName('No Project');
                             $handle->setFullName('noproject (No Project)');
                             $handle->setComplete(true);
                             break;
                         default:
                             $handle->setName('Foul Magicks');
                             break;
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_USER:
                 $object = new PhabricatorUser();
                 $users = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $users = mpull($users, null, 'getPHID');
                 $image_phids = mpull($users, 'getProfileImagePHID');
                 $image_phids = array_unique(array_filter($image_phids));
                 $images = array();
                 if ($image_phids) {
                     $images = id(new PhabricatorFile())->loadAllWhere('phid IN (%Ls)', $image_phids);
                     $images = mpull($images, 'getBestURI', 'getPHID');
                 }
                 $statuses = id(new PhabricatorUserStatus())->loadCurrentStatuses($phids);
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($users[$phid])) {
                         $handle->setName('Unknown User');
                     } else {
                         $user = $users[$phid];
                         $handle->setName($user->getUsername());
                         $handle->setURI('/p/' . $user->getUsername() . '/');
                         $handle->setFullName($user->getUsername() . ' (' . $user->getRealName() . ')');
                         $handle->setAlternateID($user->getID());
                         $handle->setComplete(true);
                         if (isset($statuses[$phid])) {
                             $handle->setStatus($statuses[$phid]->getTextStatus());
                         }
                         $handle->setDisabled($user->getIsDisabled());
                         $img_uri = idx($images, $user->getProfileImagePHID());
                         if ($img_uri) {
                             $handle->setImageURI($img_uri);
                         } else {
                             $handle->setImageURI(PhabricatorUser::getDefaultProfileImageURI());
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_MLST:
                 $object = new PhabricatorMetaMTAMailingList();
                 $lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $lists = mpull($lists, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($lists[$phid])) {
                         $handle->setName('Unknown Mailing List');
                     } else {
                         $list = $lists[$phid];
                         $handle->setName($list->getName());
                         $handle->setURI($list->getURI());
                         $handle->setFullName($list->getName());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_DREV:
                 $object = new DifferentialRevision();
                 $revs = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $revs = mpull($revs, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($revs[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $rev = $revs[$phid];
                         $handle->setName($rev->getTitle());
                         $handle->setURI('/D' . $rev->getID());
                         $handle->setFullName('D' . $rev->getID() . ': ' . $rev->getTitle());
                         $handle->setComplete(true);
                         $status = $rev->getStatus();
                         if ($status == ArcanistDifferentialRevisionStatus::CLOSED || $status == ArcanistDifferentialRevisionStatus::ABANDONED) {
                             $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
                             $handle->setStatus($closed);
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
                 $object = new PhabricatorRepositoryCommit();
                 $commits = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $commits = mpull($commits, null, 'getPHID');
                 $repository_ids = array();
                 $callsigns = array();
                 if ($commits) {
                     $repository_ids = mpull($commits, 'getRepositoryID');
                     $repositories = id(new PhabricatorRepository())->loadAllWhere('id in (%Ld)', array_unique($repository_ids));
                     $callsigns = mpull($repositories, 'getCallsign');
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($commits[$phid]) || !isset($callsigns[$repository_ids[$phid]])) {
                         $handle->setName('Unknown Commit');
                     } else {
                         $commit = $commits[$phid];
                         $callsign = $callsigns[$repository_ids[$phid]];
                         $repository = $repositories[$repository_ids[$phid]];
                         $commit_identifier = $commit->getCommitIdentifier();
                         // In case where the repository for the commit was deleted,
                         // we don't have have info about the repository anymore.
                         if ($repository) {
                             $name = $repository->formatCommitName($commit_identifier);
                             $handle->setName($name);
                         } else {
                             $handle->setName('Commit ' . 'r' . $callsign . $commit_identifier);
                         }
                         $handle->setURI('/r' . $callsign . $commit_identifier);
                         $handle->setFullName('r' . $callsign . $commit_identifier);
                         $handle->setTimestamp($commit->getEpoch());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_TASK:
                 $object = new ManiphestTask();
                 $tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $tasks = mpull($tasks, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($tasks[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $task = $tasks[$phid];
                         $handle->setName($task->getTitle());
                         $handle->setURI('/T' . $task->getID());
                         $handle->setFullName('T' . $task->getID() . ': ' . $task->getTitle());
                         $handle->setComplete(true);
                         $handle->setAlternateID($task->getID());
                         if ($task->getStatus() != ManiphestTaskStatus::STATUS_OPEN) {
                             $closed = PhabricatorObjectHandleStatus::STATUS_CLOSED;
                             $handle->setStatus($closed);
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_FILE:
                 $object = new PhabricatorFile();
                 $files = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $files = mpull($files, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($files[$phid])) {
                         $handle->setName('Unknown File');
                     } else {
                         $file = $files[$phid];
                         $handle->setName($file->getName());
                         $handle->setURI($file->getBestURI());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
                 $object = new PhabricatorProject();
                 $projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setURI('/project/view/' . $project->getID() . '/');
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_REPO:
                 $object = new PhabricatorRepository();
                 $repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $repositories = mpull($repositories, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($repositories[$phid])) {
                         $handle->setName('Unknown Repository');
                     } else {
                         $repository = $repositories[$phid];
                         $handle->setName($repository->getCallsign());
                         $handle->setURI('/diffusion/' . $repository->getCallsign() . '/');
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
                 $object = new PhabricatorOwnersPackage();
                 $packages = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $packages = mpull($packages, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($packages[$phid])) {
                         $handle->setName('Unknown Package');
                     } else {
                         $package = $packages[$phid];
                         $handle->setName($package->getName());
                         $handle->setURI('/owners/package/' . $package->getID() . '/');
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
                 $project_dao = new PhabricatorRepositoryArcanistProject();
                 $projects = $project_dao->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Arcanist Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
                 $document_dao = new PhrictionDocument();
                 $content_dao = new PhrictionContent();
                 $conn = $document_dao->establishConnection('r');
                 $documents = queryfx_all($conn, 'SELECT * FROM %T document JOIN %T content
           ON document.contentID = content.id
           WHERE document.phid IN (%Ls)', $document_dao->getTableName(), $content_dao->getTableName(), $phids);
                 $documents = ipull($documents, null, 'phid');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($documents[$phid])) {
                         $handle->setName('Unknown Document');
                     } else {
                         $info = $documents[$phid];
                         $handle->setName($info['title']);
                         $handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
                         $handle->setComplete(true);
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             default:
                 $loader = null;
                 if (isset($external_loaders[$type])) {
                     $loader = $external_loaders[$type];
                 } else {
                     if (isset($external_loaders['*'])) {
                         $loader = $external_loaders['*'];
                     }
                 }
                 if ($loader) {
                     $object = newv($loader, array());
                     $handles += $object->loadHandles($phids);
                     break;
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setType($type);
                     $handle->setPHID($phid);
                     $handle->setName('Unknown Object');
                     $handle->setFullName('An Unknown Object');
                     $handles[$phid] = $handle;
                 }
                 break;
         }
     }
     return $handles;
 }
Ejemplo n.º 16
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($this->id) {
         $document = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     } else {
         $slug = PhabricatorSlug::normalize($request->getStr('slug'));
         if (!$slug) {
             return new Aphront404Response();
         }
         $document = id(new PhrictionDocumentQuery())->setViewer($user)->withSlugs(array($slug))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     }
     if (!$document) {
         return new Aphront404Response();
     }
     if (!isset($slug)) {
         $slug = $document->getSlug();
     }
     $target_slug = PhabricatorSlug::normalize($request->getStr('new-slug', $slug));
     $submit_uri = $request->getRequestURI()->getPath();
     $cancel_uri = PhrictionDocument::getSlugURI($slug);
     $errors = array();
     $error_view = null;
     $e_url = null;
     $disallowed_statuses = array(PhrictionDocumentStatus::STATUS_DELETED => true, PhrictionDocumentStatus::STATUS_MOVED => true, PhrictionDocumentStatus::STATUS_STUB => true);
     if (isset($disallowed_statuses[$document->getStatus()])) {
         $error_dialog = id(new AphrontDialogView())->setUser($user)->setTitle('Can not move page!')->appendChild(pht('An already moved or deleted document ' . 'can not be moved again.'))->addCancelButton($cancel_uri);
         return id(new AphrontDialogResponse())->setDialog($error_dialog);
     }
     $content = id(new PhrictionContent())->load($document->getContentID());
     if ($request->isFormPost() && !count($errors)) {
         if (!count($errors)) {
             // First check if the target document exists
             // NOTE: We use the ominpotent user because we can't let users overwrite
             // documents even if they can't see them.
             $target_document = id(new PhrictionDocumentQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withSlugs(array($target_slug))->executeOne();
             // Considering to overwrite existing docs? Nuke this!
             if ($target_document && $target_document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS) {
                 $errors[] = pht('Can not overwrite existing target document.');
                 $e_url = pht('Already exists.');
             }
         }
         if (!count($errors)) {
             // I like to move it, move it!
             $from_editor = id(PhrictionDocumentEditor::newForSlug($slug))->setActor($user)->setTitle($content->getTitle())->setContent($content->getContent())->setDescription($content->getDescription());
             $target_editor = id(PhrictionDocumentEditor::newForSlug($target_slug))->setActor($user)->setTitle($content->getTitle())->setContent($content->getContent())->setDescription($content->getDescription());
             // Move it!
             $target_editor->moveHere($document->getID(), $document->getPHID());
             // Retrieve the target doc directly from the editor
             // No need to load it per Sql again
             $target_document = $target_editor->getDocument();
             $from_editor->moveAway($target_document->getID());
             $redir_uri = PhrictionDocument::getSlugURI($target_document->getSlug());
             return id(new AphrontRedirectResponse())->setURI($redir_uri);
         }
     }
     if ($errors) {
         $error_view = id(new AphrontErrorView())->setErrors($errors);
     }
     $form = id(new PHUIFormLayoutView())->setUser($user)->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Title'))->setValue($content->getTitle()))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('New URI'))->setValue($target_slug)->setError($e_url)->setName('new-slug')->setCaption(pht('The new location of the document.')))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Edit Notes'))->setValue($content->getDescription())->setError(null)->setName('description'));
     $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('Move Document'))->appendChild($form)->setSubmitURI($submit_uri)->addSubmitButton(pht('Move Document'))->addCancelButton($cancel_uri);
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 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'));
 }
Ejemplo n.º 18
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $document = id(new PhrictionDocument())->load($this->id);
     if (!$document) {
         return new Aphront404Response();
     }
     $current = id(new PhrictionContent())->load($document->getContentID());
     $l = $request->getInt('l');
     $r = $request->getInt('r');
     $ref = $request->getStr('ref');
     if ($ref) {
         list($l, $r) = explode(',', $ref);
     }
     $content = id(new PhrictionContent())->loadAllWhere('documentID = %d AND version IN (%Ld)', $document->getID(), array($l, $r));
     $content = mpull($content, null, 'getVersion');
     $content_l = idx($content, $l, null);
     $content_r = idx($content, $r, null);
     if (!$content_l || !$content_r) {
         return new Aphront404Response();
     }
     $text_l = $content_l->getContent();
     $text_r = $content_r->getContent();
     $text_l = wordwrap($text_l, 80);
     $text_r = wordwrap($text_r, 80);
     $engine = new PhabricatorDifferenceEngine();
     $changeset = $engine->generateChangesetFromFileContent($text_l, $text_r);
     $changeset->setOldProperties(array('Title' => $content_l->getTitle()));
     $changeset->setNewProperties(array('Title' => $content_r->getTitle()));
     $whitespace_mode = DifferentialChangesetParser::WHITESPACE_SHOW_ALL;
     $parser = new DifferentialChangesetParser();
     $parser->setChangeset($changeset);
     $parser->setRenderingReference("{$l},{$r}");
     $parser->setWhitespaceMode($whitespace_mode);
     $spec = $request->getStr('range');
     list($range_s, $range_e, $mask) = DifferentialChangesetParser::parseRangeSpecification($spec);
     $output = $parser->render($range_s, $range_e, $mask);
     if ($request->isAjax()) {
         return id(new PhabricatorChangesetResponse())->setRenderedChangeset($output);
     }
     require_celerity_resource('differential-changeset-view-css');
     require_celerity_resource('syntax-highlighting-css');
     require_celerity_resource('phriction-document-css');
     Javelin::initBehavior('differential-show-more', array('uri' => '/phriction/diff/' . $document->getID() . '/', 'whitespace' => $whitespace_mode));
     $slug = $document->getSlug();
     $revert_l = $this->renderRevertButton($content_l, $current);
     $revert_r = $this->renderRevertButton($content_r, $current);
     $crumbs = new AphrontCrumbsView();
     $crumbs->setCrumbs(array('Phriction', phutil_render_tag('a', array('href' => PhrictionDocument::getSlugURI($slug)), phutil_escape_html($current->getTitle())), phutil_render_tag('a', array('href' => '/phriction/history/' . $document->getSlug() . '/'), 'History'), phutil_escape_html("Changes Between Version {$l} and Version {$r}")));
     $comparison_table = $this->renderComparisonTable(array($content_r, $content_l));
     $navigation_table = null;
     if ($l + 1 == $r) {
         $nav_l = $l > 1;
         $nav_r = $r != $current->getVersion();
         $uri = $request->getRequestURI();
         if ($nav_l) {
             $link_l = phutil_render_tag('a', array('href' => $uri->alter('l', $l - 1)->alter('r', $r - 1)), "« Previous Change");
         } else {
             $link_l = 'Original Change';
         }
         $link_r = null;
         if ($nav_r) {
             $link_r = phutil_render_tag('a', array('href' => $uri->alter('l', $l + 1)->alter('r', $r + 1)), "Next Change »");
         } else {
             $link_r = 'Most Recent Change';
         }
         $navigation_table = '<table class="phriction-history-nav-table">
       <tr>
         <td class="nav-prev">' . $link_l . '</td>
         <td class="nav-next">' . $link_r . '</td>
       </tr>
     </table>';
     }
     $output = '<div class="phriction-document-history-diff">' . $comparison_table->render() . '<br />' . '<br />' . $navigation_table . '<table class="phriction-revert-table">' . '<tr><td>' . $revert_l . '</td><td>' . $revert_r . '</td>' . '</table>' . $output . '</div>';
     return $this->buildStandardPageResponse(array($crumbs, $output), array('title' => 'Document History'));
 }
 protected function buildMailBody(PhabricatorLiskDAO $object, array $xactions)
 {
     $body = parent::buildMailBody($object, $xactions);
     if ($this->getIsNewObject()) {
         $body->addRemarkupSection(pht('DOCUMENT CONTENT'), $object->getContent()->getContent());
     } else {
         if ($this->contentDiffURI) {
             $body->addLinkSection(pht('DOCUMENT DIFF'), PhabricatorEnv::getProductionURI($this->contentDiffURI));
         }
     }
     $description = $object->getContent()->getDescription();
     if (strlen($description)) {
         $body->addTextSection(pht('EDIT NOTES'), $description);
     }
     $body->addLinkSection(pht('DOCUMENT DETAIL'), PhabricatorEnv::getProductionURI(PhrictionDocument::getSlugURI($object->getSlug())));
     return $body;
 }
 private function renderChildDocumentLink(array $info)
 {
     $title = nonempty($info['title'], pht('(Untitled Document)'));
     $item = phutil_tag('a', array('href' => PhrictionDocument::getSlugURI($info['slug'])), $title);
     if (isset($info['empty'])) {
         $item = phutil_tag('em', array(), $item);
     }
     return $item;
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $document = id(new PhrictionDocumentQuery())->setViewer($viewer)->withIDs(array($id))->needContent(true)->executeOne();
     if (!$document) {
         return new Aphront404Response();
     }
     $current = $document->getContent();
     $l = $request->getInt('l');
     $r = $request->getInt('r');
     $ref = $request->getStr('ref');
     if ($ref) {
         list($l, $r) = explode(',', $ref);
     }
     $content = id(new PhrictionContent())->loadAllWhere('documentID = %d AND version IN (%Ld)', $document->getID(), array($l, $r));
     $content = mpull($content, null, 'getVersion');
     $content_l = idx($content, $l, null);
     $content_r = idx($content, $r, null);
     if (!$content_l || !$content_r) {
         return new Aphront404Response();
     }
     $text_l = $content_l->getContent();
     $text_r = $content_r->getContent();
     $diff_view = id(new PhabricatorApplicationTransactionTextDiffDetailView())->setOldText($text_l)->setNewText($text_r);
     $changes = id(new PHUIObjectBoxView())->setHeaderText(pht('Content Changes'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->appendChild(phutil_tag('div', array('class' => 'prose-diff-frame'), $diff_view));
     require_celerity_resource('phriction-document-css');
     $slug = $document->getSlug();
     $revert_l = $this->renderRevertButton($content_l, $current);
     $revert_r = $this->renderRevertButton($content_r, $current);
     $crumbs = $this->buildApplicationCrumbs();
     $crumb_views = $this->renderBreadcrumbs($slug);
     foreach ($crumb_views as $view) {
         $crumbs->addCrumb($view);
     }
     $crumbs->addTextCrumb(pht('History'), PhrictionDocument::getSlugURI($slug, 'history'));
     $title = pht('Version %s vs %s', $l, $r);
     $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-history');
     $crumbs->addTextCrumb($title, $request->getRequestURI());
     $comparison_table = $this->renderComparisonTable(array($content_r, $content_l));
     $navigation_table = null;
     if ($l + 1 == $r) {
         $nav_l = $l > 1;
         $nav_r = $r != $current->getVersion();
         $uri = $request->getRequestURI();
         if ($nav_l) {
             $link_l = phutil_tag('a', array('href' => $uri->alter('l', $l - 1)->alter('r', $r - 1), 'class' => 'button grey'), pht("« Previous Change"));
         } else {
             $link_l = phutil_tag('a', array('href' => '#', 'class' => 'button grey disabled'), pht('Original Change'));
         }
         $link_r = null;
         if ($nav_r) {
             $link_r = phutil_tag('a', array('href' => $uri->alter('l', $l + 1)->alter('r', $r + 1), 'class' => 'button grey'), pht("Next Change »"));
         } else {
             $link_r = phutil_tag('a', array('href' => '#', 'class' => 'button grey disabled'), pht('Most Recent Change'));
         }
         $navigation_table = phutil_tag('table', array('class' => 'phriction-history-nav-table'), phutil_tag('tr', array(), array(phutil_tag('td', array('class' => 'nav-prev'), $link_l), phutil_tag('td', array('class' => 'nav-next'), $link_r))));
     }
     $output = hsprintf('<div class="phriction-document-history-diff">' . '%s%s' . '<table class="phriction-revert-table">' . '<tr><td>%s</td><td>%s</td>' . '</table>' . '</div>', $comparison_table->render(), $navigation_table, $revert_l, $revert_r);
     $object_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Edits'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->appendChild($output);
     $crumbs->setBorder(true);
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($object_box, $changes));
     return $this->newPage()->setTitle(pht('Document History'))->setCrumbs($crumbs)->appendChild($view);
 }
 protected function renderInput()
 {
     $id = $this->getID();
     if (!$id) {
         $id = celerity_generate_unique_node_id();
         $this->setID($id);
     }
     $viewer = $this->getUser();
     if (!$viewer) {
         throw new PhutilInvalidStateException('setUser');
     }
     // We need to have this if previews render images, since Ajax can not
     // currently ship JS or CSS.
     require_celerity_resource('lightbox-attachment-css');
     if (!$this->getDisabled()) {
         Javelin::initBehavior('aphront-drag-and-drop-textarea', array('target' => $id, 'activatedClass' => 'aphront-textarea-drag-and-drop', 'uri' => '/file/dropupload/', 'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold()));
     }
     $root_id = celerity_generate_unique_node_id();
     $user_datasource = new PhabricatorPeopleDatasource();
     $proj_datasource = id(new PhabricatorProjectDatasource())->setParameters(array('autocomplete' => 1));
     Javelin::initBehavior('phabricator-remarkup-assist', array('pht' => array('bold text' => pht('bold text'), 'italic text' => pht('italic text'), 'monospaced text' => pht('monospaced text'), 'List Item' => pht('List Item'), 'Quoted Text' => pht('Quoted Text'), 'data' => pht('data'), 'name' => pht('name'), 'URL' => pht('URL')), 'disabled' => $this->getDisabled(), 'rootID' => $root_id, 'autocompleteMap' => (object) array(64 => array('datasourceURI' => $user_datasource->getDatasourceURI(), 'headerIcon' => 'fa-user', 'headerText' => pht('Find User:'******'hintText' => $user_datasource->getPlaceholderText()), 35 => array('datasourceURI' => $proj_datasource->getDatasourceURI(), 'headerIcon' => 'fa-briefcase', 'headerText' => pht('Find Project:'), 'hintText' => $proj_datasource->getPlaceholderText()))));
     Javelin::initBehavior('phabricator-tooltips', array());
     $actions = array('fa-bold' => array('tip' => pht('Bold'), 'nodevice' => true), 'fa-italic' => array('tip' => pht('Italics'), 'nodevice' => true), 'fa-text-width' => array('tip' => pht('Monospaced'), 'nodevice' => true), 'fa-link' => array('tip' => pht('Link'), 'nodevice' => true), array('spacer' => true, 'nodevice' => true), 'fa-list-ul' => array('tip' => pht('Bulleted List'), 'nodevice' => true), 'fa-list-ol' => array('tip' => pht('Numbered List'), 'nodevice' => true), 'fa-code' => array('tip' => pht('Code Block'), 'nodevice' => true), 'fa-quote-right' => array('tip' => pht('Quote'), 'nodevice' => true), 'fa-table' => array('tip' => pht('Table'), 'nodevice' => true), 'fa-cloud-upload' => array('tip' => pht('Upload File')));
     $can_use_macros = !$this->disableMacro && function_exists('imagettftext');
     if ($can_use_macros) {
         $can_use_macros = PhabricatorApplication::isClassInstalledForViewer('PhabricatorMacroApplication', $viewer);
     }
     if ($can_use_macros) {
         $actions[] = array('spacer' => true);
         $actions['fa-meh-o'] = array('tip' => pht('Meme'));
     }
     $actions['fa-eye'] = array('tip' => pht('Preview'), 'align' => 'right');
     $actions[] = array('spacer' => true, 'align' => 'right');
     $actions['fa-life-bouy'] = array('tip' => pht('Help'), 'align' => 'right', 'href' => PhrictionDocument::getSlugURI('usage/formatting_reference'));
     if (!$this->disableFullScreen) {
         $actions[] = array('spacer' => true, 'align' => 'right');
         $actions['fa-arrows-alt'] = array('tip' => pht('Fullscreen Mode'), 'align' => 'right');
     }
     $buttons = array();
     foreach ($actions as $action => $spec) {
         $classes = array();
         if (idx($spec, 'align') == 'right') {
             $classes[] = 'remarkup-assist-right';
         }
         if (idx($spec, 'nodevice')) {
             $classes[] = 'remarkup-assist-nodevice';
         }
         if (idx($spec, 'spacer')) {
             $classes[] = 'remarkup-assist-separator';
             $buttons[] = phutil_tag('span', array('class' => implode(' ', $classes)), '');
             continue;
         } else {
             $classes[] = 'remarkup-assist-button';
         }
         $href = idx($spec, 'href', '#');
         if ($href == '#') {
             $meta = array('action' => $action);
             $mustcapture = true;
             $target = null;
         } else {
             $meta = array();
             $mustcapture = null;
             $target = '_blank';
         }
         $content = null;
         $tip = idx($spec, 'tip');
         if ($tip) {
             $meta['tip'] = $tip;
             $content = javelin_tag('span', array('aural' => true), $tip);
         }
         $sigils = array();
         $sigils[] = 'remarkup-assist';
         if (!$this->getDisabled()) {
             $sigils[] = 'has-tooltip';
         }
         $buttons[] = javelin_tag('a', array('class' => implode(' ', $classes), 'href' => $href, 'sigil' => implode(' ', $sigils), 'meta' => $meta, 'mustcapture' => $mustcapture, 'target' => $target, 'tabindex' => -1), phutil_tag('div', array('class' => 'remarkup-assist phui-icon-view phui-font-fa bluegrey ' . $action), $content));
     }
     $buttons = phutil_tag('div', array('class' => 'remarkup-assist-bar'), $buttons);
     $monospaced_textareas = null;
     $monospaced_textareas_class = null;
     $monospaced_textareas = $viewer->loadPreferences()->getPreference(PhabricatorUserPreferences::PREFERENCE_MONOSPACED_TEXTAREAS);
     if ($monospaced_textareas == 'enabled') {
         $monospaced_textareas_class = 'PhabricatorMonospaced';
     }
     $this->setCustomClass('remarkup-assist-textarea ' . $monospaced_textareas_class);
     return javelin_tag('div', array('sigil' => 'remarkup-assist-control', 'class' => $this->getDisabled() ? 'disabled-control' : null, 'id' => $root_id), array($buttons, parent::renderInput()));
 }
 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>';
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $document = id(new PhrictionDocumentQuery())->setViewer($user)->withSlugs(array(PhabricatorSlug::normalize($this->slug)))->needContent(true)->executeOne();
     if (!$document) {
         return new Aphront404Response();
     }
     $current = $document->getContent();
     $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);
     $list = new PHUIObjectItemListView();
     $list->setFlush(true);
     foreach ($history as $content) {
         $author = $handles[$content->getAuthorPHID()]->renderLink();
         $slug_uri = PhrictionDocument::getSlugURI($document->getSlug());
         $version = $content->getVersion();
         $diff_uri = new PhutilURI('/phriction/diff/' . $document->getID() . '/');
         $vs_previous = null;
         if ($content->getVersion() != 1) {
             $vs_previous = $diff_uri->alter('l', $content->getVersion() - 1)->alter('r', $content->getVersion());
         }
         $vs_head = null;
         if ($content->getID() != $document->getContentID()) {
             $vs_head = $diff_uri->alter('l', $content->getVersion())->alter('r', $current->getVersion());
         }
         $change_type = PhrictionChangeType::getChangeTypeLabel($content->getChangeType());
         switch ($content->getChangeType()) {
             case PhrictionChangeType::CHANGE_DELETE:
                 $color = 'red';
                 break;
             case PhrictionChangeType::CHANGE_EDIT:
                 $color = 'blue';
                 break;
             case PhrictionChangeType::CHANGE_MOVE_HERE:
                 $color = 'yellow';
                 break;
             case PhrictionChangeType::CHANGE_MOVE_AWAY:
                 $color = 'orange';
                 break;
             case PhrictionChangeType::CHANGE_STUB:
                 $color = 'green';
                 break;
             default:
                 throw new Exception('Unknown change type!');
                 break;
         }
         $item = id(new PHUIObjectItemView())->setHeader(pht('%s by %s', $change_type, $author))->setBarColor($color)->addAttribute(phutil_tag('a', array('href' => $slug_uri . '?v=' . $version), pht('Version %s', $version)))->addAttribute(pht('%s %s', phabricator_date($content->getDateCreated(), $user), phabricator_time($content->getDateCreated(), $user)));
         if ($content->getDescription()) {
             $item->addAttribute($content->getDescription());
         }
         if ($vs_previous) {
             $item->addIcon('fa-reply', pht('Show Change'), array('href' => $vs_previous));
         } else {
             $item->addIcon('fa-reply grey', phutil_tag('em', array(), pht('No previous change')));
         }
         if ($vs_head) {
             $item->addIcon('fa-reply-all', pht('Show Later Changes'), array('href' => $vs_head));
         } else {
             $item->addIcon('fa-reply-all grey', phutil_tag('em', array(), pht('No later changes')));
         }
         $list->addItem($item);
     }
     $crumbs = $this->buildApplicationCrumbs();
     $crumb_views = $this->renderBreadcrumbs($document->getSlug());
     foreach ($crumb_views as $view) {
         $crumbs->addCrumb($view);
     }
     $crumbs->addTextCrumb(pht('History'), PhrictionDocument::getSlugURI($document->getSlug(), 'history'));
     $header = new PHUIHeaderView();
     $header->setHeader(pht('Document History for %s', phutil_tag('a', array('href' => PhrictionDocument::getSlugURI($document->getSlug())), head($history)->getTitle())));
     $obj_box = id(new PHUIObjectBoxView())->setHeader($header)->appendChild($list)->appendChild($pager);
     return $this->buildApplicationPage(array($crumbs, $obj_box), array('title' => pht('Document History')));
 }
 public function loadHandles()
 {
     $types = array();
     foreach ($this->phids as $phid) {
         $type = $this->lookupType($phid);
         $types[$type][] = $phid;
     }
     $handles = array();
     $external_loaders = PhabricatorEnv::getEnvConfig('phid.external-loaders');
     foreach ($types as $type => $phids) {
         switch ($type) {
             case PhabricatorPHIDConstants::PHID_TYPE_MAGIC:
                 // Black magic!
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     switch ($phid) {
                         case ManiphestTaskOwner::OWNER_UP_FOR_GRABS:
                             $handle->setName('Up For Grabs');
                             $handle->setFullName('upforgrabs (Up For Grabs)');
                             break;
                         default:
                             $handle->setName('Foul Magicks');
                             break;
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_USER:
                 $class = 'PhabricatorUser';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $users = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $users = mpull($users, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($users[$phid])) {
                         $handle->setName('Unknown User');
                     } else {
                         $user = $users[$phid];
                         $handle->setName($user->getUsername());
                         $handle->setURI('/p/' . $user->getUsername() . '/');
                         $handle->setEmail($user->getEmail());
                         $handle->setFullName($user->getUsername() . ' (' . $user->getRealName() . ')');
                         $handle->setAlternateID($user->getID());
                         $img_phid = $user->getProfileImagePHID();
                         if ($img_phid) {
                             $handle->setImageURI(PhabricatorFileURI::getViewURIForPHID($img_phid));
                         }
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_MLST:
                 $class = 'PhabricatorMetaMTAMailingList';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $lists = mpull($lists, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($lists[$phid])) {
                         $handle->setName('Unknown Mailing List');
                     } else {
                         $list = $lists[$phid];
                         $handle->setEmail($list->getEmail());
                         $handle->setName($list->getName());
                         $handle->setURI($list->getURI());
                         $handle->setFullName($list->getName());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_DREV:
                 $class = 'DifferentialRevision';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $revs = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $revs = mpull($revs, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($revs[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $rev = $revs[$phid];
                         $handle->setName($rev->getTitle());
                         $handle->setURI('/D' . $rev->getID());
                         $handle->setFullName('D' . $rev->getID() . ': ' . $rev->getTitle());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_CMIT:
                 $class = 'PhabricatorRepositoryCommit';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $commits = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $commits = mpull($commits, null, 'getPHID');
                 $repository_ids = mpull($commits, 'getRepositoryID');
                 $repositories = id(new PhabricatorRepository())->loadAllWhere('id in (%Ld)', array_unique($repository_ids));
                 $callsigns = mpull($repositories, 'getCallsign');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($commits[$phid]) || !isset($callsigns[$repository_ids[$phid]])) {
                         $handle->setName('Unknown Commit');
                     } else {
                         $commit = $commits[$phid];
                         $callsign = $callsigns[$repository_ids[$phid]];
                         $repository = $repositories[$repository_ids[$phid]];
                         $commit_identifier = $commit->getCommitIdentifier();
                         // In case where the repository for the commit was deleted,
                         // we don't have have info about the repository anymore.
                         if ($repository) {
                             $vcs = $repository->getVersionControlSystem();
                             if ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT) {
                                 $short_identifier = substr($commit_identifier, 0, 16);
                             } else {
                                 $short_identifier = $commit_identifier;
                             }
                             $handle->setName('r' . $callsign . $short_identifier);
                         } else {
                             $handle->setName('Commit ' . 'r' . $callsign . $commit_identifier);
                         }
                         $handle->setURI('/r' . $callsign . $commit_identifier);
                         $handle->setFullName('r' . $callsign . $commit_identifier);
                         $handle->setTimestamp($commit->getEpoch());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_TASK:
                 $class = 'ManiphestTask';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $tasks = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $tasks = mpull($tasks, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($tasks[$phid])) {
                         $handle->setName('Unknown Revision');
                     } else {
                         $task = $tasks[$phid];
                         $handle->setName($task->getTitle());
                         $handle->setURI('/T' . $task->getID());
                         $handle->setFullName('T' . $task->getID() . ': ' . $task->getTitle());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_FILE:
                 $class = 'PhabricatorFile';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $files = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $files = mpull($files, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($files[$phid])) {
                         $handle->setName('Unknown File');
                     } else {
                         $file = $files[$phid];
                         $handle->setName($file->getName());
                         $handle->setURI($file->getViewURI());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_PROJ:
                 $class = 'PhabricatorProject';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $projects = $object->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                         $handle->setURI('/project/view/' . $project->getID() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_REPO:
                 $class = 'PhabricatorRepository';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $repositories = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $repositories = mpull($repositories, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($repositories[$phid])) {
                         $handle->setName('Unknown Repository');
                     } else {
                         $repository = $repositories[$phid];
                         $handle->setName($repository->getCallsign());
                         $handle->setURI('/diffusion/' . $repository->getCallsign() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_OPKG:
                 $class = 'PhabricatorOwnersPackage';
                 PhutilSymbolLoader::loadClass($class);
                 $object = newv($class, array());
                 $packages = $object->loadAllWhere('phid in (%Ls)', $phids);
                 $packages = mpull($packages, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($packages[$phid])) {
                         $handle->setName('Unknown Package');
                     } else {
                         $package = $packages[$phid];
                         $handle->setName($package->getName());
                         $handle->setURI('/owners/package/' . $package->getID() . '/');
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_APRJ:
                 $project_dao = newv('PhabricatorRepositoryArcanistProject', array());
                 $projects = $project_dao->loadAllWhere('phid IN (%Ls)', $phids);
                 $projects = mpull($projects, null, 'getPHID');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($projects[$phid])) {
                         $handle->setName('Unknown Arcanist Project');
                     } else {
                         $project = $projects[$phid];
                         $handle->setName($project->getName());
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             case PhabricatorPHIDConstants::PHID_TYPE_WIKI:
                 $document_dao = newv('PhrictionDocument', array());
                 $content_dao = newv('PhrictionContent', array());
                 $conn = $document_dao->establishConnection('r');
                 $documents = queryfx_all($conn, 'SELECT * FROM %T document JOIN %T content
           ON document.contentID = content.id
           WHERE document.phid IN (%Ls)', $document_dao->getTableName(), $content_dao->getTableName(), $phids);
                 $documents = ipull($documents, null, 'phid');
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setPHID($phid);
                     $handle->setType($type);
                     if (empty($documents[$phid])) {
                         $handle->setName('Unknown Document');
                     } else {
                         $info = $documents[$phid];
                         $handle->setName($info['title']);
                         $handle->setURI(PhrictionDocument::getSlugURI($info['slug']));
                     }
                     $handles[$phid] = $handle;
                 }
                 break;
             default:
                 $loader = null;
                 if (isset($external_loaders[$type])) {
                     $loader = $external_loaders[$type];
                 } else {
                     if (isset($external_loaders['*'])) {
                         $loader = $external_loaders['*'];
                     }
                 }
                 if ($loader) {
                     PhutilSymbolLoader::loadClass($loader);
                     $object = newv($loader, array());
                     $handles += $object->loadHandles($phids);
                     break;
                 }
                 foreach ($phids as $phid) {
                     $handle = new PhabricatorObjectHandle();
                     $handle->setType($type);
                     $handle->setPHID($phid);
                     $handle->setName('Unknown Object');
                     $handle->setFullName('An Unknown Object');
                     $handles[$phid] = $handle;
                 }
                 break;
         }
     }
     return $handles;
 }
Ejemplo n.º 26
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 handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $current_version = null;
     if ($id) {
         $document = id(new PhrictionDocumentQuery())->setViewer($viewer)->withIDs(array($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($viewer)->withSlugs(array($slug))->needContent(true)->executeOne();
         if ($document) {
             $content = $document->getContent();
             $current_version = $content->getVersion();
         } else {
             $document = PhrictionDocument::initializeNewDocument($viewer, $slug);
             $content = $document->getContent();
         }
     }
     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', $viewer->getPHID(), $draft_key);
     }
     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 PHUIInfoView();
         $draft_note->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
         $draft_note->setTitle(pht('Recovered Draft'));
         $draft_note->appendChild(hsprintf('<p>%s</p>', pht('Showing a saved draft of your edits, you can %s.', $discard)));
     } else {
         $content_text = $content->getContent();
         $draft_note = null;
     }
     require_celerity_resource('phriction-document-css');
     $e_title = true;
     $e_content = true;
     $validation_exception = null;
     $notes = null;
     $title = $content->getTitle();
     $overwrite = false;
     $v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID($document->getPHID());
     if ($request->isFormPost()) {
         $title = $request->getStr('title');
         $content_text = $request->getStr('content');
         $notes = $request->getStr('description');
         $current_version = $request->getInt('contentVersion');
         $v_view = $request->getStr('viewPolicy');
         $v_edit = $request->getStr('editPolicy');
         $v_cc = $request->getArr('cc');
         $xactions = array();
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_TITLE)->setNewValue($title);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_CONTENT)->setNewValue($content_text);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)->setNewValue($v_view);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY)->setNewValue($v_edit);
         $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array('=' => $v_cc));
         $editor = id(new PhrictionTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->setDescription($notes)->setProcessContentVersionError(!$request->getBool('overwrite'))->setContentVersion($current_version);
         try {
             $editor->applyTransactions($document, $xactions);
             if ($draft) {
                 $draft->delete();
             }
             $uri = PhrictionDocument::getSlugURI($document->getSlug());
             return id(new AphrontRedirectResponse())->setURI($uri);
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $validation_exception = $ex;
             $e_title = nonempty($ex->getShortMessage(PhrictionTransaction::TYPE_TITLE), true);
             $e_content = nonempty($ex->getShortMessage(PhrictionTransaction::TYPE_CONTENT), true);
             // if we're not supposed to process the content version error, then
             // overwrite that content...!
             if (!$editor->getProcessContentVersionError()) {
                 $overwrite = true;
             }
             $document->setViewPolicy($v_view);
             $document->setEditPolicy($v_edit);
         }
     }
     if ($document->getID()) {
         $panel_header = pht('Edit Document: %s', $content->getTitle());
         $page_title = pht('Edit Document');
         $header_icon = 'fa-pencil';
         if ($overwrite) {
             $submit_button = pht('Overwrite Changes');
         } else {
             $submit_button = pht('Save Changes');
         }
     } else {
         $panel_header = pht('Create New Phriction Document');
         $submit_button = pht('Create Document');
         $page_title = pht('Create Document');
         $header_icon = 'fa-plus-square';
     }
     $uri = $document->getSlug();
     $uri = PhrictionDocument::getSlugURI($uri);
     $uri = PhabricatorEnv::getProductionURI($uri);
     $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug());
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($document)->execute();
     $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
     $edit_capability = PhabricatorPolicyCapability::CAN_EDIT;
     $form = id(new AphrontFormView())->setUser($viewer)->addHiddenInput('slug', $document->getSlug())->addHiddenInput('nodraft', $request->getBool('nodraft'))->addHiddenInput('contentVersion', $current_version)->addHiddenInput('overwrite', $overwrite)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Title'))->setValue($title)->setError($e_title)->setName('title'))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('URI'))->setValue($uri))->appendChild(id(new PhabricatorRemarkupControl())->setLabel(pht('Content'))->setValue($content_text)->setError($e_content)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setName('content')->setID('document-textarea')->setUser($viewer))->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Subscribers'))->setName('cc')->setValue($v_cc)->setUser($viewer)->setDatasource(new PhabricatorMetaMTAMailableDatasource()))->appendChild(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($document)->setCapability($view_capability)->setPolicies($policies)->setCaption($document->describeAutomaticCapability($view_capability)))->appendChild(id(new AphrontFormPolicyControl())->setName('editPolicy')->setPolicyObject($document)->setCapability($edit_capability)->setPolicies($policies)->setCaption($document->describeAutomaticCapability($edit_capability)))->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('Document'))->setValidationException($validation_exception)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $preview = id(new PHUIRemarkupPreviewPanel())->setHeader($content->getTitle())->setPreviewURI('/phriction/preview/' . $document->getSlug())->setControlID('document-textarea')->setPreviewType(PHUIRemarkupPreviewPanel::DOCUMENT);
     $crumbs = $this->buildApplicationCrumbs();
     if ($document->getID()) {
         $crumbs->addTextCrumb($content->getTitle(), PhrictionDocument::getSlugURI($document->getSlug()));
         $crumbs->addTextCrumb(pht('Edit'));
     } else {
         $crumbs->addTextCrumb(pht('Create'));
     }
     $crumbs->setBorder(true);
     $header = id(new PHUIHeaderView())->setHeader($panel_header)->setHeaderIcon($header_icon);
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($draft_note, $form_box, $preview));
     return $this->newPage()->setTitle($page_title)->setCrumbs($crumbs)->appendChild($view);
 }
Ejemplo n.º 28
0
 private function sendMailToSubscribers(array $subscribers, $old_content)
 {
     if (!$subscribers) {
         return;
     }
     $author_phid = $this->getActor()->getPHID();
     $document = $this->document;
     $content = $document->getContent();
     $slug_uri = PhrictionDocument::getSlugURI($document->getSlug());
     $diff_uri = new PhutilURI('/phriction/diff/' . $document->getID() . '/');
     $prod_uri = PhabricatorEnv::getProductionURI('');
     $vs_head = $diff_uri->alter('l', $old_content->getVersion())->alter('r', $content->getVersion());
     $old_title = $old_content->getTitle();
     $title = $content->getTitle();
     $name = $this->getChangeTypeDescription($content->getChangeType(), $title);
     $action = PhrictionChangeType::getChangeTypeLabel($content->getChangeType());
     $body = array($name);
     // Content may have changed, you never know
     if ($content->getChangeType() == PhrictionChangeType::CHANGE_EDIT) {
         if ($old_title != $title) {
             $body[] = pht('Title was changed from "%s" to "%s"', $old_title, $title);
         }
         $body[] = pht("Link to new version:\n%s", $prod_uri . $slug_uri . '?v=' . $content->getVersion());
         $body[] = pht("Link to diff:\n%s", $prod_uri . $vs_head);
     } else {
         if ($content->getChangeType() == PhrictionChangeType::CHANGE_MOVE_AWAY) {
             $target_document = id(new PhrictionDocument())->load($content->getChangeRef());
             $slug_uri = PhrictionDocument::getSlugURI($target_document->getSlug());
             $body[] = pht("Link to destination document:\n%s", $prod_uri . $slug_uri);
         }
     }
     $body = implode("\n\n", $body);
     $subject_prefix = $this->getMailSubjectPrefix();
     $mail = new PhabricatorMetaMTAMail();
     $mail->setSubject($name)->setSubjectPrefix($subject_prefix)->setVarySubjectPrefix('[' . $action . ']')->addHeader('Thread-Topic', $name)->setFrom($author_phid)->addTos($subscribers)->setBody($body)->setRelatedPHID($document->getPHID())->setIsBulk(true);
     $mail->saveAndSend();
 }
Ejemplo n.º 29
0
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $document = id(new PhrictionDocumentQuery())->setViewer($user)->withIDs(array($this->id))->needContent(true)->executeOne();
     if (!$document) {
         return new Aphront404Response();
     }
     $current = $document->getContent();
     $l = $request->getInt('l');
     $r = $request->getInt('r');
     $ref = $request->getStr('ref');
     if ($ref) {
         list($l, $r) = explode(',', $ref);
     }
     $content = id(new PhrictionContent())->loadAllWhere('documentID = %d AND version IN (%Ld)', $document->getID(), array($l, $r));
     $content = mpull($content, null, 'getVersion');
     $content_l = idx($content, $l, null);
     $content_r = idx($content, $r, null);
     if (!$content_l || !$content_r) {
         return new Aphront404Response();
     }
     $text_l = $content_l->getContent();
     $text_r = $content_r->getContent();
     $text_l = phutil_utf8_hard_wrap($text_l, 80);
     $text_l = implode("\n", $text_l);
     $text_r = phutil_utf8_hard_wrap($text_r, 80);
     $text_r = implode("\n", $text_r);
     $engine = new PhabricatorDifferenceEngine();
     $changeset = $engine->generateChangesetFromFileContent($text_l, $text_r);
     $changeset->setOldProperties(array('Title' => $content_l->getTitle()));
     $changeset->setNewProperties(array('Title' => $content_r->getTitle()));
     $whitespace_mode = DifferentialChangesetParser::WHITESPACE_SHOW_ALL;
     $parser = new DifferentialChangesetParser();
     $parser->setChangeset($changeset);
     $parser->setRenderingReference("{$l},{$r}");
     $parser->setWhitespaceMode($whitespace_mode);
     $engine = new PhabricatorMarkupEngine();
     $engine->setViewer($user);
     $engine->process();
     $parser->setMarkupEngine($engine);
     $spec = $request->getStr('range');
     list($range_s, $range_e, $mask) = DifferentialChangesetParser::parseRangeSpecification($spec);
     $output = $parser->render($range_s, $range_e, $mask);
     if ($request->isAjax()) {
         return id(new PhabricatorChangesetResponse())->setRenderedChangeset($output);
     }
     require_celerity_resource('differential-changeset-view-css');
     require_celerity_resource('syntax-highlighting-css');
     require_celerity_resource('phriction-document-css');
     Javelin::initBehavior('differential-show-more', array('uri' => '/phriction/diff/' . $document->getID() . '/', 'whitespace' => $whitespace_mode));
     $slug = $document->getSlug();
     $revert_l = $this->renderRevertButton($content_l, $current);
     $revert_r = $this->renderRevertButton($content_r, $current);
     $crumbs = $this->buildApplicationCrumbs();
     $crumb_views = $this->renderBreadcrumbs($slug);
     foreach ($crumb_views as $view) {
         $crumbs->addCrumb($view);
     }
     $crumbs->addTextCrumb(pht('History'), PhrictionDocument::getSlugURI($slug, 'history'));
     $title = pht('Version %s vs %s', $l, $r);
     $header = id(new PHUIHeaderView())->setHeader($title);
     $crumbs->addTextCrumb($title, $request->getRequestURI());
     $comparison_table = $this->renderComparisonTable(array($content_r, $content_l));
     $navigation_table = null;
     if ($l + 1 == $r) {
         $nav_l = $l > 1;
         $nav_r = $r != $current->getVersion();
         $uri = $request->getRequestURI();
         if ($nav_l) {
             $link_l = phutil_tag('a', array('href' => $uri->alter('l', $l - 1)->alter('r', $r - 1), 'class' => 'button'), pht("« Previous Change"));
         } else {
             $link_l = phutil_tag('a', array('href' => '#', 'class' => 'button grey disabled'), pht('Original Change'));
         }
         $link_r = null;
         if ($nav_r) {
             $link_r = phutil_tag('a', array('href' => $uri->alter('l', $l + 1)->alter('r', $r + 1), 'class' => 'button'), pht("Next Change »"));
         } else {
             $link_r = phutil_tag('a', array('href' => '#', 'class' => 'button grey disabled'), pht('Most Recent Change'));
         }
         $navigation_table = phutil_tag('table', array('class' => 'phriction-history-nav-table'), phutil_tag('tr', array(), array(phutil_tag('td', array('class' => 'nav-prev'), $link_l), phutil_tag('td', array('class' => 'nav-next'), $link_r))));
     }
     $output = hsprintf('<div class="phriction-document-history-diff">' . '%s%s' . '<table class="phriction-revert-table">' . '<tr><td>%s</td><td>%s</td>' . '</table>' . '%s' . '</div>', $comparison_table->render(), $navigation_table, $revert_l, $revert_r, $output);
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->appendChild($output);
     return $this->buildApplicationPage(array($crumbs, $object_box), array('title' => pht('Document History')));
 }
Ejemplo n.º 30
0
 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'));
 }