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