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 handleRequest(AphrontRequest $request)
 {
     $user = $request->getUser();
     $id = $request->getURIData('id');
     if ($id) {
         $post = id(new PhamePostQuery())->setViewer($user)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$post) {
             return new Aphront404Response();
         }
         $cancel_uri = $this->getApplicationURI('/post/view/' . $id . '/');
         $submit_button = pht('Save Changes');
         $page_title = pht('Edit Post');
     } else {
         $blog = id(new PhameBlogQuery())->setViewer($user)->withIDs(array($request->getInt('blog')))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_JOIN))->executeOne();
         if (!$blog) {
             return new Aphront404Response();
         }
         $post = PhamePost::initializePost($user, $blog);
         $cancel_uri = $this->getApplicationURI('/blog/view/' . $blog->getID() . '/');
         $submit_button = pht('Save Draft');
         $page_title = pht('Create Post');
     }
     $title = $post->getTitle();
     $phame_title = $post->getPhameTitle();
     $body = $post->getBody();
     $comments_widget = $post->getCommentsWidget();
     $e_title = true;
     $e_phame_title = true;
     $validation_exception = null;
     if ($request->isFormPost()) {
         $title = $request->getStr('title');
         $phame_title = $request->getStr('phame_title');
         $phame_title = PhabricatorSlug::normalize($phame_title);
         $body = $request->getStr('body');
         $comments_widget = $request->getStr('comments_widget');
         $xactions = array(id(new PhamePostTransaction())->setTransactionType(PhamePostTransaction::TYPE_TITLE)->setNewValue($title), id(new PhamePostTransaction())->setTransactionType(PhamePostTransaction::TYPE_PHAME_TITLE)->setNewValue($phame_title), id(new PhamePostTransaction())->setTransactionType(PhamePostTransaction::TYPE_BODY)->setNewValue($body), id(new PhamePostTransaction())->setTransactionType(PhamePostTransaction::TYPE_COMMENTS_WIDGET)->setNewValue($comments_widget));
         $editor = id(new PhamePostEditor())->setActor($user)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true);
         try {
             $editor->applyTransactions($post, $xactions);
             $uri = $this->getApplicationURI('/post/view/' . $post->getID() . '/');
             return id(new AphrontRedirectResponse())->setURI($uri);
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $validation_exception = $ex;
             $e_title = $validation_exception->getShortMessage(PhamePostTransaction::TYPE_TITLE);
             $e_phame_title = $validation_exception->getShortMessage(PhamePostTransaction::TYPE_PHAME_TITLE);
         }
     }
     $handle = id(new PhabricatorHandleQuery())->setViewer($user)->withPHIDs(array($post->getBlogPHID()))->executeOne();
     $form = id(new AphrontFormView())->setUser($user)->addHiddenInput('blog', $request->getInt('blog'))->appendChild(id(new AphrontFormMarkupControl())->setLabel(pht('Blog'))->setValue($handle->renderLink()))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Title'))->setName('title')->setValue($title)->setID('post-title')->setError($e_title))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Phame Title'))->setName('phame_title')->setValue(rtrim($phame_title, '/'))->setID('post-phame-title')->setCaption(pht('Up to 64 alphanumeric characters ' . 'with underscores for spaces. ' . 'Formatting is enforced.'))->setError($e_phame_title))->appendChild(id(new PhabricatorRemarkupControl())->setLabel(pht('Body'))->setName('body')->setValue($body)->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL)->setID('post-body')->setUser($user)->setDisableMacros(true))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Comments Widget'))->setName('comments_widget')->setvalue($comments_widget)->setOptions($post->getCommentsWidgetOptionsForSelect()))->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($submit_button));
     $loading = phutil_tag_div('aphront-panel-preview-loading-text', pht('Loading preview...'));
     $preview_panel = phutil_tag_div('aphront-panel-preview', array(phutil_tag_div('phame-post-preview-header', pht('Post Preview')), phutil_tag('div', array('id' => 'post-preview'), $loading)));
     require_celerity_resource('phame-css');
     Javelin::initBehavior('phame-post-preview', array('preview' => 'post-preview', 'body' => 'post-body', 'title' => 'post-title', 'phame_title' => 'post-phame-title', 'uri' => '/phame/post/preview/'));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($page_title)->setValidationException($validation_exception)->setForm($form);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($page_title, $this->getApplicationURI('/post/view/' . $id . '/'));
     $nav = $this->renderSideNavFilterView(null);
     $nav->appendChild(array($crumbs, $form_box, $preview_panel));
     return $this->buildApplicationPage($nav, array('title' => $page_title));
 }
 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();
     $slug = PhabricatorSlug::normalize($request->getStr('slug'));
     if ($request->isFormPost()) {
         $document = id(new PhrictionDocumentQuery())->setViewer($user)->withSlugs(array($slug))->executeOne();
         $prompt = $request->getStr('prompt', 'no');
         $document_exists = $document && $document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS;
         if ($document_exists && $prompt == 'no') {
             $dialog = new AphrontDialogView();
             $dialog->setSubmitURI('/phriction/new/')->setTitle(pht('Edit Existing Document?'))->setUser($user)->appendChild(pht('The document %s already exists. Do you want to edit it instead?', phutil_tag('tt', array(), $slug)))->addHiddenInput('slug', $slug)->addHiddenInput('prompt', 'yes')->addCancelButton('/w/')->addSubmitButton(pht('Edit Document'));
             return id(new AphrontDialogResponse())->setDialog($dialog);
         } else {
             if (PhrictionDocument::isProjectSlug($slug)) {
                 $project = id(new PhabricatorProjectQuery())->setViewer($user)->withPhrictionSlugs(array(PhrictionDocument::getProjectSlugIdentifier($slug)))->executeOne();
                 if (!$project) {
                     $dialog = new AphrontDialogView();
                     $dialog->setSubmitURI('/w/')->setTitle(pht('Oops!'))->setUser($user)->appendChild(pht('You cannot create wiki pages under "projects/",
               because they are reserved as project pages.
               Create a new project with this name first.'))->addCancelButton('/w/', 'Okay');
                     return id(new AphrontDialogResponse())->setDialog($dialog);
                 }
             }
         }
         $uri = '/phriction/edit/?slug=' . $slug;
         return id(new AphrontRedirectResponse())->setURI($uri);
     }
     if ($slug == '/') {
         $slug = '';
     }
     $view = id(new PHUIFormLayoutView())->appendChild(id(new AphrontFormTextControl())->setLabel('/w/')->setValue($slug)->setName('slug'));
     $dialog = id(new AphrontDialogView())->setUser($user)->setTitle(pht('New Document'))->setSubmitURI('/phriction/new/')->appendChild(phutil_tag('p', array(), pht('Create a new document at')))->appendChild($view)->addSubmitButton(pht('Create'))->addCancelButton('/w/');
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 protected function loadPage()
 {
     $table = new PhrictionDocument();
     $conn_r = $table->establishConnection('r');
     $rows = queryfx_all($conn_r, 'SELECT * FROM %T %Q %Q %Q', $table->getTableName(), $this->buildWhereClause($conn_r), $this->buildOrderClause($conn_r), $this->buildLimitClause($conn_r));
     $documents = $table->loadAllFromArray($rows);
     if ($documents) {
         $ancestor_slugs = array();
         foreach ($documents as $key => $document) {
             $document_slug = $document->getSlug();
             foreach (PhabricatorSlug::getAncestry($document_slug) as $ancestor) {
                 $ancestor_slugs[$ancestor][] = $key;
             }
         }
         if ($ancestor_slugs) {
             $ancestors = queryfx_all($conn_r, 'SELECT * FROM %T WHERE slug IN (%Ls)', $document->getTableName(), array_keys($ancestor_slugs));
             $ancestors = $table->loadAllFromArray($ancestors);
             $ancestors = mpull($ancestors, null, 'getSlug');
             foreach ($ancestor_slugs as $ancestor_slug => $document_keys) {
                 $ancestor = idx($ancestors, $ancestor_slug);
                 foreach ($document_keys as $document_key) {
                     $documents[$document_key]->attachAncestor($ancestor_slug, $ancestor);
                 }
             }
         }
     }
     return $documents;
 }
 protected function buildLocalNavigation(PhabricatorProject $project)
 {
     $id = $project->getID();
     $nav_view = new AphrontSideNavFilterView();
     $uri = new PhutilURI('/project/view/' . $id . '/');
     $nav_view->setBaseURI($uri);
     $external_arrow = "↗";
     $tasks_uri = '/maniphest/view/all/?projects=' . $project->getPHID();
     $slug = PhabricatorSlug::normalize($project->getName());
     $phriction_uri = '/w/projects/' . $slug;
     $edit_uri = '/project/edit/' . $id . '/';
     $members_uri = '/project/members/' . $id . '/';
     $nav_view->addFilter('dashboard', 'Dashboard');
     $nav_view->addSpacer();
     $nav_view->addFilter('feed', 'Feed');
     $nav_view->addFilter(null, 'Tasks ' . $external_arrow, $tasks_uri);
     $nav_view->addFilter(null, 'Wiki ' . $external_arrow, $phriction_uri);
     $nav_view->addFilter('people', 'People');
     $nav_view->addFilter('about', 'About');
     $user = $this->getRequest()->getUser();
     $can_edit = PhabricatorPolicyCapability::CAN_EDIT;
     $nav_view->addSpacer();
     if (PhabricatorPolicyFilter::hasCapability($user, $project, $can_edit)) {
         $nav_view->addFilter('edit', "Edit Project…", $edit_uri);
         $nav_view->addFilter('members', "Edit Members…", $members_uri);
     } else {
         $nav_view->addFilter('edit', "Edit Project…", $edit_uri, $relative = false, 'disabled');
         $nav_view->addFilter('members', "Edit Members…", $members_uri, $relative = false, 'disabled');
     }
     return $nav_view;
 }
 public function testSlugDepth()
 {
     $slugs = array('/' => 0, 'a/' => 1, 'a/b/' => 2, 'a////b/' => 2);
     foreach ($slugs as $slug => $depth) {
         $this->assertEqual($depth, PhabricatorSlug::getDepth($slug), "Depth of '{$slug}'");
     }
 }
示例#8
0
 public static function getProjectSlugIdentifier($slug)
 {
     if (!self::isProjectSlug($slug)) {
         throw new Exception("Slug '{$slug}' is not a project slug!");
     }
     $slug = PhabricatorSlug::normalize($slug);
     $parts = explode('/', $slug);
     return $parts[1] . '/';
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $slug = $request->getValue('slug');
     $document = id(new PhrictionDocumentQuery())->setViewer($request->getUser())->withSlugs(array(PhabricatorSlug::normalize($slug)))->needContent(true)->executeOne();
     if (!$document) {
         throw new ConduitException('ERR-BAD-DOCUMENT');
     }
     return $this->buildDocumentInfoDictionary($document, $document->getContent());
 }
 private function buildProjectActions(PhutilEvent $event)
 {
     if (!$this->canUseApplication($event->getUser())) {
         return null;
     }
     $project = $event->getValue('object');
     $slug = PhabricatorSlug::normalize($project->getPhrictionSlug());
     $href = '/w/projects/' . $slug;
     return id(new PhabricatorActionView())->setIcon('fa-book')->setName(pht('View Wiki'))->setHref($href);
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $slug = $request->getValue('slug');
     $doc = id(new PhrictionDocumentQuery())->setViewer($request->getUser())->withSlugs(array(PhabricatorSlug::normalize($slug)))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$doc) {
         throw new Exception(pht('No such document.'));
     }
     $editor = id(PhrictionDocumentEditor::newForSlug($slug))->setActor($request->getUser())->setTitle($request->getValue('title'))->setContent($request->getValue('content'))->setDescription($request->getvalue('description'))->save();
     return $this->buildDocumentInfoDictionary($editor->getDocument());
 }
 public function markupDocumentLink($matches)
 {
     $slug = trim($matches[1]);
     $name = trim(idx($matches, 2, $slug));
     $name = explode('/', trim($name, '/'));
     $name = end($name);
     $slug = PhabricatorSlug::normalize($slug);
     $uri = PhrictionDocument::getSlugURI($slug);
     return $this->getEngine()->storeText(phutil_render_tag('a', array('href' => $uri, 'class' => 'phriction-link'), phutil_escape_html($name)));
 }
示例#13
0
 public function setPhrictionSlug($slug)
 {
     // NOTE: We're doing a little magic here and stripping out '/' so that
     // project pages always appear at top level under projects/ even if the
     // display name is "Hack / Slash" or similar (it will become
     // 'hack_slash' instead of 'hack/slash').
     $slug = str_replace('/', ' ', $slug);
     $slug = PhabricatorSlug::normalize($slug);
     $this->phrictionSlug = $slug;
     return $this;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $slug = $request->getValue('slug');
     $doc = id(new PhrictionDocument())->loadOneWhere('slug = %s', PhabricatorSlug::normalize($slug));
     if (!$doc) {
         throw new ConduitException('ERR-BAD-DOCUMENT');
     }
     $content = id(new PhrictionContent())->load($doc->getContentID());
     $doc->attachContent($content);
     return $this->buildDocumentInfoDictionary($doc);
 }
示例#15
0
 public function getViewURI($blogger_name = '')
 {
     // go for the pretty uri if we can
     if ($blogger_name) {
         $phame_title = PhabricatorSlug::normalize($this->getPhameTitle());
         $uri = phutil_escape_uri('/phame/posts/' . $blogger_name . '/' . $phame_title);
     } else {
         $uri = $this->getActionURI('view');
     }
     return $uri;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $query = new PhabricatorProjectQuery();
     $query->setViewer($request->getUser());
     $query->needMembers(true);
     $query->needSlugs(true);
     $ids = $request->getValue('ids');
     if ($ids) {
         $query->withIDs($ids);
     }
     $names = $request->getValue('names');
     if ($names) {
         $query->withNames($names);
     }
     $status = $request->getValue('status');
     if ($status) {
         $query->withStatus($status);
     }
     $phids = $request->getValue('phids');
     if ($phids) {
         $query->withPHIDs($phids);
     }
     $slugs = $request->getValue('slugs');
     if ($slugs) {
         $query->withSlugs($slugs);
     }
     $members = $request->getValue('members');
     if ($members) {
         $query->withMemberPHIDs($members);
     }
     $limit = $request->getValue('limit');
     if ($limit) {
         $query->setLimit($limit);
     }
     $offset = $request->getValue('offset');
     if ($offset) {
         $query->setOffset($offset);
     }
     $pager = $this->newPager($request);
     $results = $query->executeWithCursorPager($pager);
     $projects = $this->buildProjectInfoDictionaries($results);
     // TODO: This is pretty hideous.
     $slug_map = array();
     foreach ($slugs as $slug) {
         $normal = rtrim(PhabricatorSlug::normalize($slug), '/');
         foreach ($projects as $project) {
             if (in_array($normal, $project['slugs'])) {
                 $slug_map[$slug] = $project['phid'];
             }
         }
     }
     $result = array('data' => $projects, 'slugMap' => $slug_map);
     return $this->addPagerResults($result, $pager);
 }
示例#17
0
 public function getViewURI()
 {
     // go for the pretty uri if we can
     $domain = $this->blog ? $this->blog->getDomain() : '';
     if ($domain) {
         $phame_title = PhabricatorSlug::normalize($this->getPhameTitle());
         return 'http://' . $domain . '/post/' . $phame_title;
     }
     $uri = '/phame/post/view/' . $this->getID() . '/';
     return PhabricatorEnv::getProductionURI($uri);
 }
 protected function loadProject()
 {
     $viewer = $this->getViewer();
     $request = $this->getRequest();
     $id = nonempty($request->getURIData('projectID'), $request->getURIData('id'));
     $slug = $request->getURIData('slug');
     if ($slug) {
         $normal_slug = PhabricatorSlug::normalizeProjectSlug($slug);
         $is_abnormal = $slug !== $normal_slug;
         $normal_uri = "/tag/{$normal_slug}/";
     } else {
         $is_abnormal = false;
     }
     $query = id(new PhabricatorProjectQuery())->setViewer($viewer)->needMembers(true)->needWatchers(true)->needImages(true)->needSlugs(true);
     if ($slug) {
         $query->withSlugs(array($slug));
     } else {
         $query->withIDs(array($id));
     }
     $policy_exception = null;
     try {
         $project = $query->executeOne();
     } catch (PhabricatorPolicyException $ex) {
         $policy_exception = $ex;
         $project = null;
     }
     if (!$project) {
         // This project legitimately does not exist, so just 404 the user.
         if (!$policy_exception) {
             return new Aphront404Response();
         }
         // Here, the project exists but the user can't see it. If they are
         // using a non-canonical slug to view the project, redirect to the
         // canonical slug. If they're already using the canonical slug, rethrow
         // the exception to give them the policy error.
         if ($is_abnormal) {
             return id(new AphrontRedirectResponse())->setURI($normal_uri);
         } else {
             throw $policy_exception;
         }
     }
     // The user can view the project, but is using a noncanonical slug.
     // Redirect to the canonical slug.
     $primary_slug = $project->getPrimarySlug();
     if ($slug && $slug !== $primary_slug) {
         $primary_uri = "/tag/{$primary_slug}/";
         return id(new AphrontRedirectResponse())->setURI($primary_uri);
     }
     $this->setProject($project);
     return null;
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $slug = $request->getValue('slug');
     $doc = id(new PhrictionDocument())->loadOneWhere('slug = %s', PhabricatorSlug::normalize($slug));
     if (!$doc) {
         throw new ConduitException('ERR-BAD-DOCUMENT');
     }
     $content = id(new PhrictionContent())->loadAllWhere('documentID = %d ORDER BY version DESC', $doc->getID());
     $results = array();
     foreach ($content as $version) {
         $results[] = $this->buildDocumentContentDictionary($doc, $version);
     }
     return $results;
 }
 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);
 }
 private function getNormalizedURI($slug)
 {
     if (!strlen($slug)) {
         return null;
     }
     $normal = PhabricatorSlug::normalizeProjectSlug($slug);
     if ($normal === $slug) {
         return null;
     }
     $viewer = $this->getViewer();
     // Do execute() instead of executeOne() here so we canonicalize before
     // raising a policy exception. This is a little more polished than letting
     // the user hit the error on any variant of the slug.
     $projects = id(new PhabricatorProjectQuery())->setViewer($viewer)->withSlugs(array($normal))->execute();
     if (!$projects) {
         return null;
     }
     return "/tag/{$normal}/";
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $slug = $request->getValue('slug');
     $doc = id(new PhrictionDocumentQuery())->setViewer($request->getUser())->withSlugs(array(PhabricatorSlug::normalize($slug)))->needContent(true)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$doc) {
         throw new Exception(pht('No such document.'));
     }
     $xactions = array();
     $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_TITLE)->setNewValue($request->getValue('title'));
     $xactions[] = id(new PhrictionTransaction())->setTransactionType(PhrictionTransaction::TYPE_CONTENT)->setNewValue($request->getValue('content'));
     $editor = id(new PhrictionTransactionEditor())->setActor($request->getUser())->setContentSourceFromConduitRequest($request)->setContinueOnNoEffect(true)->setDescription($request->getValue('description'));
     try {
         $editor->applyTransactions($doc, $xactions);
     } catch (PhabricatorApplicationTransactionValidationException $ex) {
         // TODO - some magical hotness via T5873
         throw $ex;
     }
     return $this->buildDocumentInfoDictionary($doc);
 }
 protected function execute(ConduitAPIRequest $request)
 {
     $user = $request->getUser();
     $blog_phid = $request->getValue('blogPHID');
     $title = $request->getValue('title');
     $body = $request->getValue('body');
     $exception_description = array();
     if (!$blog_phid) {
         $exception_description[] = pht('No blog phid.');
     }
     if (!strlen($title)) {
         $exception_description[] = pht('No post title.');
     }
     if (!strlen($body)) {
         $exception_description[] = pht('No post body.');
     }
     if ($exception_description) {
         throw id(new ConduitException('ERR-INVALID-PARAMETER'))->setErrorDescription(implode("\n", $exception_description));
     }
     $blogger_phid = $request->getValue('bloggerPHID');
     if ($blogger_phid) {
         $blogger = id(new PhabricatorPeopleQuery())->setViewer($user)->withPHIDs(array($blogger_phid))->executeOne();
     } else {
         $blogger = $user;
     }
     $blog = id(new PhameBlogQuery())->setViewer($blogger)->withPHIDs(array($blog_phid))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_JOIN))->executeOne();
     if (!$blog) {
         throw new ConduitException('ERR-INVALID-BLOG');
     }
     $post = PhamePost::initializePost($blogger, $blog);
     $is_draft = $request->getValue('isDraft', false);
     if (!$is_draft) {
         $post->setDatePublished(time());
         $post->setVisibility(PhamePost::VISIBILITY_PUBLISHED);
     }
     $post->setTitle($title);
     $phame_title = $request->getValue('phameTitle', id(new PhutilUTF8StringTruncator())->setMaximumBytes(64)->truncateString($title));
     $post->setPhameTitle(PhabricatorSlug::normalize($phame_title));
     $post->setBody($body);
     $post->save();
     return $post->toDictionary();
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $slug = PhabricatorSlug::normalize($request->getStr('slug'));
     if ($request->isFormPost()) {
         $document = id(new PhrictionDocumentQuery())->setViewer($viewer)->withSlugs(array($slug))->executeOne();
         $prompt = $request->getStr('prompt', 'no');
         $document_exists = $document && $document->getStatus() == PhrictionDocumentStatus::STATUS_EXISTS;
         if ($document_exists && $prompt == 'no') {
             return $this->newDialog()->setSubmitURI('/phriction/new/')->setTitle(pht('Edit Existing Document?'))->setUser($viewer)->appendChild(pht('The document %s already exists. Do you want to edit it instead?', phutil_tag('tt', array(), $slug)))->addHiddenInput('slug', $slug)->addHiddenInput('prompt', 'yes')->addCancelButton('/w/')->addSubmitButton(pht('Edit Document'));
         }
         $uri = '/phriction/edit/?slug=' . $slug;
         return id(new AphrontRedirectResponse())->setURI($uri);
     }
     if ($slug == '/') {
         $slug = '';
     }
     $view = id(new PHUIFormLayoutView())->appendChild(id(new AphrontFormTextControl())->setLabel('/w/')->setValue($slug)->setName('slug'));
     return $this->newDialog()->setTitle(pht('New Document'))->setSubmitURI('/phriction/new/')->appendChild(phutil_tag('p', array(), pht('Create a new document at')))->appendChild($view)->addSubmitButton(pht('Create'))->addCancelButton('/w/');
 }
 public static function newForSlug($slug)
 {
     $slug = PhabricatorSlug::normalize($slug);
     $document = id(new PhrictionDocument())->loadOneWhere('slug = %s', $slug);
     $content = null;
     if ($document) {
         $content = id(new PhrictionContent())->load($document->getContentID());
     } else {
         $document = new PhrictionDocument();
         $document->setSlug($slug);
     }
     if (!$content) {
         $default_title = PhabricatorSlug::getDefaultTitle($slug);
         $content = new PhrictionContent();
         $content->setSlug($slug);
         $content->setTitle($default_title);
         $content->setContent('');
     }
     $obj = new PhrictionDocumentEditor();
     $obj->document = $document;
     $obj->content = $content;
     return $obj;
 }
/**
 * Rename the project so that it has a unique slug, by appending (2), (3), etc.
 * to its name.
 */
function rename_project($project, $projects)
{
    $suffix = 2;
    while (true) {
        $new_name = $project->getName() . ' (' . $suffix . ')';
        $new_slug = PhabricatorSlug::normalizeProjectSlug($new_name) . '/';
        $okay = true;
        foreach ($projects as $other) {
            if ($other->getID() == $project->getID()) {
                continue;
            }
            if ($other->getPhrictionSlug() == $new_slug) {
                $okay = false;
                break;
            }
        }
        if ($okay) {
            break;
        } else {
            $suffix++;
        }
    }
    return $new_name;
}
 protected function willExecute()
 {
     $this->slugMap = array();
     $this->slugNormals = array();
     $this->allSlugs = array();
     if ($this->slugs) {
         foreach ($this->slugs as $slug) {
             if (PhabricatorSlug::isValidProjectSlug($slug)) {
                 $normal = PhabricatorSlug::normalizeProjectSlug($slug);
                 $this->slugNormals[$slug] = $normal;
                 $this->allSlugs[$normal] = $normal;
             }
             // NOTE: At least for now, we query for the normalized slugs but also
             // for the slugs exactly as entered. This allows older projects with
             // slugs that are no longer valid to continue to work.
             $this->allSlugs[$slug] = $slug;
         }
     }
 }
 private function normalizeSlugs(array $slugs)
 {
     foreach ($slugs as $key => $slug) {
         $slugs[$key] = PhabricatorSlug::normalizeProjectSlug($slug);
     }
     $slugs = array_unique($slugs);
     $slugs = array_values($slugs);
     return $slugs;
 }
 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);
 }